Commit | Line | Data |
---|---|---|
a3869972 BJ |
1 | /* Copyright (c) 1979 Regents of the University of California */ |
2 | /* | |
3 | * The editor uses a temporary file for files being edited, in a structure | |
4 | * similar to that of ed. The first block of the file is used for a header | |
5 | * block which guides recovery after editor/system crashes. | |
6 | * Lines are represented in core by a pointer into the temporary file which | |
7 | * is packed into 16 bits. 15 of these bits index the temporary file, | |
8 | * the 16'th is used by global commands. The parameters below control | |
9 | * how much the 15 bits are shifted left before they index the temp file. | |
10 | * Larger shifts give more slop in the temp file but allow larger files | |
11 | * to be edited. | |
12 | * | |
13 | * The editor does not garbage collect the temporary file. When a new | |
14 | * file is edited, the temporary file is rather discarded and a new one | |
15 | * created for the new file. Garbage collection would be rather complicated | |
16 | * in ex because of the general undo, and in any case would require more | |
17 | * work when throwing lines away because marks would have be carefully | |
18 | * checked before reallocating temporary file space. Said another way, | |
19 | * each time you create a new line in the temporary file you get a unique | |
20 | * number back, and this is a property used by marks. | |
21 | * | |
22 | * The following temp file parameters allow 256k bytes in the temporary | |
23 | * file. By changing to the numbers in comments you can get 512k. | |
24 | * By typedefing line to long (32 bit) integers you could get much more | |
25 | * space in the temp file with (then) no waste. This would double core | |
26 | * requirements and would probably require some editor debugging. | |
27 | */ | |
28 | #define BLKMSK 0777 /* 01777 */ | |
29 | #define BNDRY 8 /* 16 */ | |
30 | #define INCRMT 0200 /* 0100 */ | |
31 | #define LBTMSK 0770 /* 0760 */ | |
32 | #define NMBLKS 506 /* 1018 */ | |
33 | #define OFFBTS 7 /* 6 */ | |
34 | #define OFFMSK 0177 /* 077 */ | |
35 | #define SHFT 2 /* 3 */ | |
36 | ||
37 | /* | |
38 | * The editor uses three buffers into the temporary file (ed uses two | |
39 | * and is very similar). These are two read buffers and one write buffer. | |
40 | * Basically, the editor deals with the file as a sequence of 512 character | |
41 | * blocks (BUFSIZ). Each block contains some number of lines (and lines | |
42 | * can run across block boundaries. | |
43 | * | |
44 | * New lines are written into the last block in the temporary file | |
45 | * which is in core as obuf. When a line is needed which isn't in obuf, | |
46 | * then it is brought into an input buffer. As there are two, the choice | |
47 | * is to take the buffer into which the last read (of the two) didn't go. | |
48 | * Thus this is a 2 buffer LRU replacement strategy. Measurement | |
49 | * shows that this saves roughly 25% of the buffer reads over a one | |
50 | * input buffer strategy. Since the editor (on our VAX over 1 week) | |
51 | * spends (spent) roughly 30% of its time in the system read routine, | |
52 | * this can be a big help. | |
53 | */ | |
54 | bool hitin2; /* Last read hit was ibuff2 not ibuff */ | |
55 | bool ichang2; /* Have actually changed ibuff2 */ | |
56 | bool ichanged; /* Have actually changed ibuff */ | |
57 | short iblock; /* Temp file block number of ibuff (or -1) */ | |
58 | short iblock2; /* Temp file block number of ibuff2 (or -1) */ | |
59 | short ninbuf; /* Number useful chars left in input buffer */ | |
60 | short nleft; /* Number usable chars left in output buffer */ | |
61 | short oblock; /* Temp file block number of obuff (or -1) */ | |
62 | short tline; /* Current temp file ptr */ | |
63 | ||
64 | char ibuff[BUFSIZ]; | |
65 | char ibuff2[BUFSIZ]; | |
66 | char obuff[BUFSIZ]; | |
67 | ||
68 | /* | |
69 | * Structure of the descriptor block which resides | |
70 | * in the first block of the temporary file and is | |
71 | * the guiding light for crash recovery. | |
72 | * | |
73 | * As the Blocks field below implies, there are temporary file blocks | |
74 | * devoted to (some) image of the incore array of pointers into the temp | |
75 | * file. Thus, to recover from a crash we use these indices to get the | |
76 | * line pointers back, and then use the line pointers to get the text back. | |
77 | * Except for possible lost lines due to sandbagged I/O, the entire | |
78 | * file (at the time of the last editor "sync") can be recovered from | |
79 | * the temp file. | |
80 | */ | |
81 | ||
82 | /* This definition also appears in expreserve.c... beware */ | |
83 | struct header { | |
84 | time_t Time; /* Time temp file last updated */ | |
85 | short Uid; | |
86 | short Flines; /* Number of lines in file */ | |
87 | char Savedfile[FNSIZE]; /* The current file name */ | |
88 | short Blocks[LBLKS]; /* Blocks where line pointers stashed */ | |
89 | } H; | |
90 | ||
91 | #define uid H.Uid | |
92 | #define flines H.Flines | |
93 | #define savedfile H.Savedfile | |
94 | #define blocks H.Blocks |