home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
editor
/
j414src.arc
/
TEMP.H
< prev
next >
Wrap
C/C++ Source or Header
|
1989-10-10
|
4KB
|
73 lines
/***************************************************************************
* 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)