home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / jove-4.16-src.tgz / tar.out / bsd / jove / temp.h < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  95 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986-1996 by Jonathan Payne.  JOVE is  *
  3.  * provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is *
  5.  * included in all the files.                                           *
  6.  ************************************************************************/
  7.  
  8. /*
  9.    The tmp file stores lines of text for JOVE buffers as contiguous
  10.    sequences of chars, terminated by NUL.  New lines are added to
  11.    the end of the tmp file.  The file is not garbage collected
  12.    because that would be too painful.  As a result, commands like
  13.    Yank and Kill are really easy; basically all we do is make copies
  14.    of the disk addresses of the lines (as opposed to the contents).
  15.    So, putline(char *buf) writes buf to the disk and returns a new
  16.    disk address.  getline(daddr addr, char *buf) is the opposite of
  17.    putline().  f_getputl(LinePtr line, File fp) reads from open fp
  18.    directly into the tmp file (into the buffer cache (see below))
  19.    and stores the address in line.  This is used during read_file to
  20.    minimize copying.
  21.  
  22.    To reduce the size of a tmp file disk address, each disk address
  23.    is limited to point to positions that are the start of a chunk.
  24.    A chunk has exactly CHNK_CHARS characters, so that an disk
  25.    address can be reduced by log2(CHNK_CHARS) bits.  These extra
  26.    bits allow for a larger tmp file.  This is exploited on machines
  27.    where the disk address is stored in a 16-bit type (for other
  28.    machines, a chunk is simply one character).  Using chunks wastes
  29.    some tmp file space since lines must be aligned on CHNK_CHARS
  30.    boundaries.
  31.  
  32.    The tmp file is accessed by blocks of size JBLKSIZE (typically
  33.    512 bytes or larger).  Lines do NOT cross block bounderies in the
  34.    tmp file so that accessing the contents of lines can be much
  35.    faster.  Pointers into the interior of disk buffers are returned
  36.    instead of copying the contents into local arrays and then using
  37.    them.  This cuts down on the amount of copying a great deal, at
  38.    the expense of space efficiency.
  39.  
  40.    The high bit of each disk address is used for marking the line as
  41.    needing redisplay (DIRTY).  In theory, this has nothing to do
  42.    with a disk address, but it is the cheapest place to hide a bit
  43.    in struct line (this is important since instances of this struct
  44.    are the major consumer of memory).
  45.  
  46.    The type daddr is used to represent the disk address of a line.
  47.    It is an integer containing three packed fields: the dirty bit,
  48.    the block number (within the tmp file), and the chunk number
  49.    (within the block).  Many of the following definitions are for
  50.    packing and unpacking daddr values.
  51.  
  52.    There is a buffer cache of NBUF buffers (64 on !SMALL machines and the
  53.    3 on small ones).  The blocks are stored in LRU order and each block
  54.    is also stored in a hash table by block #.  When a block is requested
  55.    it can quickly be looked up in the hash table.  If it's not there the
  56.    LRU block is assigned the new block #.  If it finds that the LRU block
  57.    is dirty (i.e., has pending IO) it syncs the WHOLE tmp file, i.e.,
  58.    does all the pending writes.  This works much better on floppy disk
  59.    systems, like the IBM PC, if the blocks are sorted before sync'ing. */
  60.  
  61. /* select chunk size by specifiying its log2 */
  62.  
  63. #ifdef SMALL
  64. # define LG_CHNK_CHARS        4    /* save bits in daddr at cost of space in tempfile */
  65. #else
  66. # define LG_CHNK_CHARS        0
  67. #endif
  68.  
  69. /* MAX_BLOCKS is the number of distinct block numbers that
  70.  * can be represented in a daddr (a power of two!).
  71.  * In fact, we don't allow block number MAX_BLOCKS-1 to be
  72.  * used because NOWHERE_DADDR and NOTYET_DADDR must not
  73.  * be valid disk references, and we want to prevent space overflow
  74.  * from being undetected through arithmetic overflow.
  75.  *
  76.  * MAX_BLOCKS is based on the number of bits remaining in daddr to
  77.  * represent it, after space for the offset (in chunks) and the
  78.  * DDIRTY bit is accounted for.
  79.  */
  80. #define MAX_BLOCKS        ((daddr) 1 << (sizeof(daddr)*CHAR_BITS - JLGBUFSIZ + LG_CHNK_CHARS - 1))
  81.  
  82. /* CHNK_CHARS is how big each chunk is.  For each 1 the DFree pointer
  83.    is incremented we extend the tmp file by CHNK_CHARS characters.
  84.    BLK_CHNKS is the # of chunks per block.
  85.  
  86.    NOTE:  It's pretty important that these numbers be powers of 2.
  87.       Be careful if you change things. */
  88.  
  89. #define CHNK_CHARS        ((daddr)1 << LG_CHNK_CHARS)
  90. #define REQ_CHNKS(chars)    (((daddr)(chars) + (CHNK_CHARS - 1)) >> LG_CHNK_CHARS)
  91. #define BLK_CHNKS        ((daddr)JBUFSIZ / CHNK_CHARS)
  92. #define blk_chop(addr)        ((daddr)(addr) & ~(BLK_CHNKS - 1))
  93. #define da_to_bno(addr)        (((daddr)(addr) >> (JLGBUFSIZ - LG_CHNK_CHARS)) & (MAX_BLOCKS - 1))
  94. #define da_to_off(addr)        (((daddr)(addr) << LG_CHNK_CHARS) & ((daddr)JBUFSIZ - 1))
  95.