home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- * is provided to you without charge, and with no warranty. You may give *
- * away copies of JOVE, including sources, provided that this notice is *
- * included in all the files. *
- ***************************************************************************/
-
- /* The tmp file is indexed in chunks of CH_SIZE characters. CH_SIZE is
- (1 << CH_BITS). New lines are added to the end of the tmp file. The
- file is not garbage collected because that would be too painful. As a
- result, commands like Yank and Kill are really easy; basically all we
- do is make copies of the disk addresses of the lines (as opposed to
- the contents). So, putline(buf) writes BUF to the disk and returns a
- new disk address. Getline(addr, buf) is the opposite of putline().
- f_getputl(line, fp) reads from open FP directly into the tmp file (into
- the buffer cache (see below)) and stores the address in LINE. This is
- used during read_file to minimize compying.
-
- Lines do NOT cross block bounderies in the tmp file so that accessing
- the contents of lines can be much faster. Pointers to offsets into
- disk buffers are returned instead of copying the contents into local
- arrays and then using them. This cuts down on the amount of copying a
- great deal, at the expense of less efficiency. The lower bit of disk
- addresses is used for marking lines as needing redisplay done.
-
- There is a buffer cache of NBUF buffers (64 on !SMALL machines and the
- 3 on small ones). The blocks are stored in LRU order and each block
- is also stored in a hash table by block #. When a block is requested
- it can quickly be looked up in the hash table. If it's not there the
- LRU block is assigned the new block #. If it finds that the LRU block
- is dirty (i.e., has pending IO) it syncs the WHOLE tmp file, i.e.,
- does all the pending writes. This works much better on floppy disk
- systems, like the IBM PC, if the blocks are sorted before sync'ing. */
-
- #ifdef SMALL
- # define CH_BITS 4
- # if JBUFSIZ == 512
- # define MAX_BLOCKS 1024
- # else
- # define MAX_BLOCKS 512
- # endif
- #else
- # define CH_BITS 0
- # define MAX_BLOCKS 4096 /* basically unlimited */
- #endif /* SMALL */
-
- #if JBUFSIZ == 512
- # define BNO_SHIFT (9 - CH_BITS)
- #else
- # define BNO_SHIFT (10 - CH_BITS)
- #endif
-
- /* CH_SIZE is how big each chunk is. For each 1 the DFree pointer
- is incremented we extend the tmp file by CH_SIZE characters.
- CH_PBLOCK is the # of chunks per block. RND_MASK is used to mask
- off the lower order bits of the daddr to round down to the beginning
- of a block. OFF_MASK masks off the higher order bits so we can get
- at the offset into the disk buffer.
-
- NOTE: It's pretty important that these numbers be multiples of
- 2. Be careful if you change things. */
-
- #define CH_SIZE ((daddr) 1 << CH_BITS)
- #define CH_PBLOCK ((daddr) JBUFSIZ / CH_SIZE)
- #define RND_MASK ((daddr) CH_PBLOCK - 1)
- #define OFF_MASK ((daddr) JBUFSIZ - 1)
- #define BNO_MASK ((daddr) MAX_BLOCKS - 1)
- #define blk_round(addr) ((daddr) (addr) & ~RND_MASK)
- #define forward_block(addr) ((daddr) (addr) + CH_PBLOCK)
- #define da_to_bno(addr) ((daddr) ((addr) >> BNO_SHIFT) & BNO_MASK)
- #define da_to_off(addr) ((daddr) ((addr) << CH_BITS) & OFF_MASK)
- #define da_too_huge(addr) ((daddr) ((addr) >> BNO_SHIFT) >= MAX_BLOCKS)
-