1: /***************************************************************************
2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
3: * is 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: /* The tmp file is indexed in chunks of CH_SIZE characters. CH_SIZE is
9: (1 << CH_BITS). New lines are added to the end of the tmp file. The
10: file is not garbage collected because that would be too painful. As a
11: result, commands like Yank and Kill are really easy; basically all we
12: do is make copies of the disk addresses of the lines (as opposed to
13: the contents). So, putline(buf) writes BUF to the disk and returns a
14: new disk address. Getline(addr, buf) is the opposite of putline().
15: f_getputl(line, fp) reads from open FP directly into the tmp file (into
16: the buffer cache (see below)) and stores the address in LINE. This is
17: used during read_file to minimize compying.
18:
19: Lines do NOT cross block bounderies in the tmp file so that accessing
20: the contents of lines can be much faster. Pointers to offsets into
21: disk buffers are returned instead of copying the contents into local
22: arrays and then using them. This cuts down on the amount of copying a
23: great deal, at the expense of less efficiency. The lower bit of disk
24: addresses is used for marking lines as needing redisplay done.
25:
26: There is a buffer cache of NBUF buffers (64 on !SMALL machines and the
27: 3 on small ones). The blocks are stored in LRU order and each block
28: is also stored in a hash table by block #. When a block is requested
29: it can quickly be looked up in the hash table. If it's not there the
30: LRU block is assigned the new block #. If it finds that the LRU block
31: is dirty (i.e., has pending IO) it syncs the WHOLE tmp file, i.e.,
32: does all the pending writes. This works much better on floppy disk
33: systems, like the IBM PC, if the blocks are sorted before sync'ing. */
34:
35: #ifdef SMALL
36: # define CH_BITS 4
37: # if BUFSIZ == 512
38: # define MAX_BLOCKS 1024
39: # else
40: # define MAX_BLOCKS 512
41: # endif
42: #else
43: # define CH_BITS 0
44: # define MAX_BLOCKS 4096 /* basically unlimited */
45: #endif /* SMALL */
46:
47: #if BUFSIZ == 512
48: # define BNO_SHIFT (9 - CH_BITS)
49: #else
50: # define BNO_SHIFT (10 - CH_BITS)
51: #endif
52:
53: /* CH_SIZE is how big each chunk is. For each 1 the DFree pointer
54: is incremented we extend the tmp file by CH_SIZE characters.
55: CH_PBLOCK is the # of chunks per block. RND_MASK is used to mask
56: off the lower order bits of the daddr to round down to the beginning
57: of a block. OFF_MASK masks off the higher order bits so we can get
58: at the offset into the disk buffer.
59:
60: NOTE: It's pretty important that these numbers be multiples of
61: 2. Be careful if you change things. */
62: #ifndef MAC
63: #define CH_SIZE (1 << CH_BITS)
64: #define CH_PBLOCK (BUFSIZ / CH_SIZE)
65: #define RND_MASK (CH_PBLOCK - 1)
66: #define OFF_MASK (BUFSIZ - 1)
67: #define BNO_MASK (MAX_BLOCKS - 1)
68: #define blk_round(daddr) (daddr & ~RND_MASK)
69: #define forward_block(daddr) (daddr + CH_PBLOCK)
70: #define da_to_bno(daddr) ((daddr >> BNO_SHIFT) & BNO_MASK)
71: #define da_to_off(daddr) ((daddr << CH_BITS) & OFF_MASK)
72: #define da_too_huge(daddr) ((daddr >> BNO_SHIFT) >= MAX_BLOCKS)
73: #else
74: #define CH_SIZE ((disk_line)1 << CH_BITS)
75: #define CH_PBLOCK ((disk_line)BUFSIZ / CH_SIZE)
76: #define RND_MASK ((disk_line)CH_PBLOCK - 1)
77: #define OFF_MASK ((disk_line)BUFSIZ - 1)
78: #define BNO_MASK ((disk_line)MAX_BLOCKS - 1)
79: #define blk_round(daddr) ((disk_line)daddr & ~RND_MASK)
80: #define forward_block(daddr) ((disk_line)daddr + CH_PBLOCK)
81: #define da_to_bno(daddr) ((disk_line)(daddr >> BNO_SHIFT) & BNO_MASK)
82: #define da_to_off(daddr) ((disk_line)(daddr << CH_BITS) & OFF_MASK)
83: #define da_too_huge(daddr) ((disk_line)(daddr >> BNO_SHIFT) >= MAX_BLOCKS)
84: #endif
Defined macros
Usage of this include