|
|
1.1 ! root 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 JBUFSIZ == 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 JBUFSIZ == 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: ! 63: #define CH_SIZE ((daddr) 1 << CH_BITS) ! 64: #define CH_PBLOCK ((daddr) JBUFSIZ / CH_SIZE) ! 65: #define RND_MASK ((daddr) CH_PBLOCK - 1) ! 66: #define OFF_MASK ((daddr) JBUFSIZ - 1) ! 67: #define BNO_MASK ((daddr) MAX_BLOCKS - 1) ! 68: #define blk_round(addr) ((daddr) (addr) & ~RND_MASK) ! 69: #define forward_block(addr) ((daddr) (addr) + CH_PBLOCK) ! 70: #define da_to_bno(addr) ((daddr) ((addr) >> BNO_SHIFT) & BNO_MASK) ! 71: #define da_to_off(addr) ((daddr) ((addr) << CH_BITS) & OFF_MASK) ! 72: #define da_too_huge(addr) ((daddr) ((addr) >> BNO_SHIFT) >= MAX_BLOCKS)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.