diff options
| author | Karl Heuer | 1995-03-17 00:46:57 +0000 |
|---|---|---|
| committer | Karl Heuer | 1995-03-17 00:46:57 +0000 |
| commit | b9c5136fd6b10fb04072ccee411697246cfe85dc (patch) | |
| tree | f77be35c6a8f5efc209e439f8e30aa60b512816b /src/region-cache.h | |
| parent | 509ed182e72c2ab97863948e19693217347c1072 (diff) | |
| download | emacs-b9c5136fd6b10fb04072ccee411697246cfe85dc.tar.gz emacs-b9c5136fd6b10fb04072ccee411697246cfe85dc.zip | |
Initial revision
Diffstat (limited to 'src/region-cache.h')
| -rw-r--r-- | src/region-cache.h | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/region-cache.h b/src/region-cache.h new file mode 100644 index 00000000000..b9f20fc4f58 --- /dev/null +++ b/src/region-cache.h | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | /* Header file: Caching facts about regions of the buffer, for optimization. | ||
| 2 | Copyright (C) 1985, 1986, 1993 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | |||
| 21 | /* This code was written by Jim Blandy <jimb@cs.oberlin.edu> to help | ||
| 22 | GNU Emacs better support the gene editor written for the University | ||
| 23 | of Illinois at Urbana-Champagne's Ribosome Database Project (RDP). | ||
| 24 | |||
| 25 | Emacs implements line operations (finding the beginning/end of the | ||
| 26 | line, vertical motion, all the redisplay stuff) by searching for | ||
| 27 | newlines in the buffer. Usually, this is a good design; it's very | ||
| 28 | clean to just represent the buffer as an unstructured string of | ||
| 29 | characters, and the lines in most files are very short (less than | ||
| 30 | eighty characters), meaning that scanning usually costs about the | ||
| 31 | same as the overhead of maintaining some more complicated data | ||
| 32 | structure. | ||
| 33 | |||
| 34 | However, some applications, like gene editing, make use of very | ||
| 35 | long lines --- on the order of tens of kilobytes. In such cases, | ||
| 36 | it may well be worthwhile to try to avoid scanning, because the | ||
| 37 | scans have become two orders of magnitude more expensive. It would | ||
| 38 | be nice if this speedup could preserve the simplicity of the | ||
| 39 | existing data structure, and disturb as little of the existing code | ||
| 40 | as possible. | ||
| 41 | |||
| 42 | So here's the tack. We add some caching to the scan_buffer | ||
| 43 | function, so that when it searches for a newline, it notes that the | ||
| 44 | region between the start and end of the search contained no | ||
| 45 | newlines; then, the next time around, it consults this cache to see | ||
| 46 | if there are regions of text it can skip over completely. The | ||
| 47 | buffer modification primitives invalidate this cache. | ||
| 48 | |||
| 49 | (Note: Since the redisplay code needs similar information on | ||
| 50 | modified regions of the buffer, we can use the code that helps out | ||
| 51 | redisplay as a guide to where we need to add our own code to | ||
| 52 | invalidate our cache. prepare_to_modify_buffer seems to be the | ||
| 53 | central spot.) | ||
| 54 | |||
| 55 | Note that the cache code itself never mentions newlines | ||
| 56 | specifically, so if you wanted to cache other properties of regions | ||
| 57 | of the buffer, you could use this code pretty much unchanged. So | ||
| 58 | this cache really holds "known/unknown" information --- "I know | ||
| 59 | this region has property P" vs. "I don't know if this region has | ||
| 60 | property P or not." */ | ||
| 61 | |||
| 62 | |||
| 63 | /* Allocate, initialize and return a new, empty region cache. */ | ||
| 64 | struct region_cache *new_region_cache ( /* void */ ); | ||
| 65 | |||
| 66 | /* Free a region cache. */ | ||
| 67 | void free_region_cache ( /* struct region_cache * */ ); | ||
| 68 | |||
| 69 | /* Assert that the region of BUF between START and END (absolute | ||
| 70 | buffer positions) is "known," for the purposes of CACHE (e.g. "has | ||
| 71 | no newlines", in the case of the line cache). */ | ||
| 72 | extern void know_region_cache ( /* struct buffer *BUF, | ||
| 73 | struct region_cache *CACHE, | ||
| 74 | int START, END */ ); | ||
| 75 | |||
| 76 | /* Indicate that a section of BUF has changed, to invalidate CACHE. | ||
| 77 | HEAD is the number of chars unchanged at the beginning of the buffer. | ||
| 78 | TAIL is the number of chars unchanged at the end of the buffer. | ||
| 79 | NOTE: this is *not* the same as the ending position of modified | ||
| 80 | region. | ||
| 81 | (This way of specifying regions makes more sense than absolute | ||
| 82 | buffer positions in the presence of insertions and deletions; the | ||
| 83 | args to pass are the same before and after such an operation.) */ | ||
| 84 | extern void invalidate_region_cache ( /* struct buffer *BUF, | ||
| 85 | struct region_cache *CACHE, | ||
| 86 | int HEAD, TAIL */ ); | ||
| 87 | |||
| 88 | /* The scanning functions. | ||
| 89 | |||
| 90 | Basically, if you're scanning forward/backward from position POS, | ||
| 91 | and region_cache_forward/backward returns true, you can skip all | ||
| 92 | the text between POS and *NEXT. And if the function returns false, | ||
| 93 | you should examine all the text from POS to *NEXT, and call | ||
| 94 | know_region_cache depending on what you find there; this way, you | ||
| 95 | might be able to avoid scanning it again. */ | ||
| 96 | |||
| 97 | /* Return true if the text immediately after POS in BUF is known, for | ||
| 98 | the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest | ||
| 99 | position after POS where the knownness changes. */ | ||
| 100 | extern int region_cache_forward ( /* struct buffer *BUF, | ||
| 101 | struct region_cache *CACHE, | ||
| 102 | int POS, | ||
| 103 | int *NEXT */ ); | ||
| 104 | |||
| 105 | /* Return true if the text immediately before POS in BUF is known, for | ||
| 106 | the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest | ||
| 107 | position before POS where the knownness changes. */ | ||
| 108 | extern int region_cache_backward ( /* struct buffer *BUF, | ||
| 109 | struct region_cache *CACHE, | ||
| 110 | int POS, | ||
| 111 | int *NEXT */ ); | ||