annotate src/region-cache.c @ 99492:ee792794d888

(isearch-search-fun): Compare the length of the current search string with the length of the string from the previous search state to detect the situation when the user adds or removes characters in the search string. Use word-search-forward-lax and word-search-backward-lax in this case, and otherwise word-search-forward and word-search-backward.
author Juri Linkov <juri@jurta.org>
date Tue, 11 Nov 2008 19:43:09 +0000
parents 8971ddf55736
children e038c1a8307c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
1 /* Caching facts about regions of the buffer, for optimization.
75227
e90d04cd455a Update copyright for years from Emacs 21 to present (mainly adding
Glenn Morris <rgm@gnu.org>
parents: 68651
diff changeset
2 Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1995, 2001, 2002, 2003,
79759
fc2bcd2a8aad Add 2008 to copyright years.
Glenn Morris <rgm@gnu.org>
parents: 78260
diff changeset
3 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
4
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
5 This file is part of GNU Emacs.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
6
94963
8971ddf55736 Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 79759
diff changeset
7 GNU Emacs is free software: you can redistribute it and/or modify
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
8 it under the terms of the GNU General Public License as published by
94963
8971ddf55736 Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 79759
diff changeset
9 the Free Software Foundation, either version 3 of the License, or
8971ddf55736 Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 79759
diff changeset
10 (at your option) any later version.
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
11
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
12 GNU Emacs is distributed in the hope that it will be useful,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
15 GNU General Public License for more details.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
16
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
94963
8971ddf55736 Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 79759
diff changeset
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
19
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
20
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
21 #include <config.h>
53901
d85f8f2e71f7 Move include stdio.h to same place as in other files.
Jan Djärv <jan.h.d@swipnet.se>
parents: 52401
diff changeset
22 #include <stdio.h>
d85f8f2e71f7 Move include stdio.h to same place as in other files.
Jan Djärv <jan.h.d@swipnet.se>
parents: 52401
diff changeset
23
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
24 #include "lisp.h"
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
25 #include "buffer.h"
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
26 #include "region-cache.h"
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
27
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
28
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
29 /* Data structures. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
30
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
31 /* The region cache.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
32
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
33 We want something that maps character positions in a buffer onto
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
34 values. The representation should deal well with long runs of
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
35 characters with the same value.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
36
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
37 The tricky part: the representation should be very cheap to
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
38 maintain in the presence of many insertions and deletions. If the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
39 overhead of maintaining the cache is too high, the speedups it
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
40 offers will be worthless.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
41
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
42
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
43 We represent the region cache as a sorted array of struct
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
44 boundary's, each of which contains a buffer position and a value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
45 the value applies to all the characters after the buffer position,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
46 until the position of the next boundary, or the end of the buffer.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
47
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
48 The cache always has a boundary whose position is BUF_BEG, so
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
49 there's always a value associated with every character in the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
50 buffer. Since the cache is sorted, this is always the first
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
51 element of the cache.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
52
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
53 To facilitate the insertion and deletion of boundaries in the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
54 cache, the cache has a gap, just like Emacs's text buffers do.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
55
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
56 To help boundary positions float along with insertions and
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
57 deletions, all boundary positions before the cache gap are stored
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
58 relative to BUF_BEG (buf) (thus they're >= 0), and all boundary
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
59 positions after the gap are stored relative to BUF_Z (buf) (thus
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
60 they're <= 0). Look at BOUNDARY_POS to see this in action. See
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
61 revalidate_region_cache to see how this helps. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
62
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
63 struct boundary {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
64 int pos;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
65 int value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
66 };
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
67
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
68 struct region_cache {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
69 /* A sorted array of locations where the known-ness of the buffer
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
70 changes. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
71 struct boundary *boundaries;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
72
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
73 /* boundaries[gap_start ... gap_start + gap_len - 1] is the gap. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
74 int gap_start, gap_len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
75
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
76 /* The number of elements allocated to boundaries, not including the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
77 gap. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
78 int cache_len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
79
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
80 /* The areas that haven't changed since the last time we cleaned out
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
81 invalid entries from the cache. These overlap when the buffer is
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
82 entirely unchanged. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
83 int beg_unchanged, end_unchanged;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
84
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
85 /* The first and last positions in the buffer. Because boundaries
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
86 store their positions relative to the start (BEG) and end (Z) of
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
87 the buffer, knowing these positions allows us to accurately
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
88 interpret positions without having to pass the buffer structure
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
89 or its endpoints around all the time.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
90
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
91 Yes, buffer_beg is always 1. It's there for symmetry with
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
92 buffer_end and the BEG and BUF_BEG macros. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
93 int buffer_beg, buffer_end;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
94 };
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
95
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
96 /* Return the position of boundary i in cache c. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
97 #define BOUNDARY_POS(c, i) \
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
98 ((i) < (c)->gap_start \
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
99 ? (c)->buffer_beg + (c)->boundaries[(i)].pos \
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
100 : (c)->buffer_end + (c)->boundaries[(c)->gap_len + (i)].pos)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
101
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
102 /* Return the value for text after boundary i in cache c. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
103 #define BOUNDARY_VALUE(c, i) \
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
104 ((i) < (c)->gap_start \
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
105 ? (c)->boundaries[(i)].value \
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
106 : (c)->boundaries[(c)->gap_len + (i)].value)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
107
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
108 /* Set the value for text after boundary i in cache c to v. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
109 #define SET_BOUNDARY_VALUE(c, i, v) \
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
110 ((i) < (c)->gap_start \
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
111 ? ((c)->boundaries[(i)].value = (v))\
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
112 : ((c)->boundaries[(c)->gap_len + (i)].value = (v)))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
113
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
114
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
115 /* How many elements to add to the gap when we resize the buffer. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
116 #define NEW_CACHE_GAP (40)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
117
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
118 /* See invalidate_region_cache; if an invalidation would throw away
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
119 information about this many characters, call
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
120 revalidate_region_cache before doing the new invalidation, to
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
121 preserve that information, instead of throwing it away. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
122 #define PRESERVE_THRESHOLD (500)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
123
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
124 static void revalidate_region_cache ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
125
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
126
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
127 /* Interface: Allocating, initializing, and disposing of region caches. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
128
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
129 struct region_cache *
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
130 new_region_cache ()
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
131 {
49600
23a1cea22d13 Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents: 44621
diff changeset
132 struct region_cache *c
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
133 = (struct region_cache *) xmalloc (sizeof (struct region_cache));
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
134
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
135 c->gap_start = 0;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
136 c->gap_len = NEW_CACHE_GAP;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
137 c->cache_len = 0;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
138 c->boundaries =
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
139 (struct boundary *) xmalloc ((c->gap_len + c->cache_len)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
140 * sizeof (*c->boundaries));
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
141
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
142 c->beg_unchanged = 0;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
143 c->end_unchanged = 0;
44621
f713f6056d87 (new_region_cache): Use BEG.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 14186
diff changeset
144 c->buffer_beg = BEG;
f713f6056d87 (new_region_cache): Use BEG.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 14186
diff changeset
145 c->buffer_end = BEG;
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
146
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
147 /* Insert the boundary for the buffer start. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
148 c->cache_len++;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
149 c->gap_len--;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
150 c->gap_start++;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
151 c->boundaries[0].pos = 0; /* from buffer_beg */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
152 c->boundaries[0].value = 0;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
153
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
154 return c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
155 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
156
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
157 void
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
158 free_region_cache (c)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
159 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
160 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
161 xfree (c->boundaries);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
162 xfree (c);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
163 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
164
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
165
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
166 /* Finding positions in the cache. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
167
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
168 /* Return the index of the last boundary in cache C at or before POS.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
169 In other words, return the boundary that specifies the value for
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
170 the region POS..(POS + 1).
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
171
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
172 This operation should be logarithmic in the number of cache
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
173 entries. It would be nice if it took advantage of locality of
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
174 reference, too, by searching entries near the last entry found. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
175 static int
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
176 find_cache_boundary (c, pos)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
177 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
178 int pos;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
179 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
180 int low = 0, high = c->cache_len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
181
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
182 while (low + 1 < high)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
183 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
184 /* mid is always a valid index, because low < high and ">> 1"
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
185 rounds down. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
186 int mid = (low + high) >> 1;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
187 int boundary = BOUNDARY_POS (c, mid);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
188
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
189 if (pos < boundary)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
190 high = mid;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
191 else
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
192 low = mid;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
193 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
194
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
195 /* Some testing. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
196 if (BOUNDARY_POS (c, low) > pos
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
197 || (low + 1 < c->cache_len
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
198 && BOUNDARY_POS (c, low + 1) <= pos))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
199 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
200
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
201 return low;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
202 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
203
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
204
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
205
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
206 /* Moving the cache gap around, inserting, and deleting. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
207
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
208
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
209 /* Move the gap of cache C to index POS, and make sure it has space
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
210 for at least MIN_SIZE boundaries. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
211 static void
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
212 move_cache_gap (c, pos, min_size)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
213 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
214 int pos;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
215 int min_size;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
216 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
217 /* Copy these out of the cache and into registers. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
218 int gap_start = c->gap_start;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
219 int gap_len = c->gap_len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
220 int buffer_beg = c->buffer_beg;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
221 int buffer_end = c->buffer_end;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
222
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
223 if (pos < 0
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
224 || pos > c->cache_len)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
225 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
226
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
227 /* We mustn't ever try to put the gap before the dummy start
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
228 boundary. That must always be start-relative. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
229 if (pos == 0)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
230 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
231
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
232 /* Need we move the gap right? */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
233 while (gap_start < pos)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
234 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
235 /* Copy one boundary from after to before the gap, and
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
236 convert its position to start-relative. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
237 c->boundaries[gap_start].pos
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
238 = (buffer_end
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
239 + c->boundaries[gap_start + gap_len].pos
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
240 - buffer_beg);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
241 c->boundaries[gap_start].value
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
242 = c->boundaries[gap_start + gap_len].value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
243 gap_start++;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
244 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
245
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
246 /* To enlarge the gap, we need to re-allocate the boundary array, and
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
247 then shift the area after the gap to the new end. Since the cost
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
248 is proportional to the amount of stuff after the gap, we do the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
249 enlargement here, after a right shift but before a left shift,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
250 when the portion after the gap is smallest. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
251 if (gap_len < min_size)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
252 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
253 int i;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
254
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
255 /* Always make at least NEW_CACHE_GAP elements, as long as we're
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
256 expanding anyway. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
257 if (min_size < NEW_CACHE_GAP)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
258 min_size = NEW_CACHE_GAP;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
259
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
260 c->boundaries =
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
261 (struct boundary *) xrealloc (c->boundaries,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
262 ((min_size + c->cache_len)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
263 * sizeof (*c->boundaries)));
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
264
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
265 /* Some systems don't provide a version of the copy routine that
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
266 can be trusted to shift memory upward into an overlapping
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
267 region. memmove isn't widely available. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
268 min_size -= gap_len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
269 for (i = c->cache_len - 1; i >= gap_start; i--)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
270 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
271 c->boundaries[i + min_size].pos = c->boundaries[i + gap_len].pos;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
272 c->boundaries[i + min_size].value = c->boundaries[i + gap_len].value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
273 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
274
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
275 gap_len = min_size;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
276 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
277
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
278 /* Need we move the gap left? */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
279 while (pos < gap_start)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
280 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
281 gap_start--;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
282
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
283 /* Copy one region from before to after the gap, and
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
284 convert its position to end-relative. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
285 c->boundaries[gap_start + gap_len].pos
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
286 = c->boundaries[gap_start].pos + buffer_beg - buffer_end;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
287 c->boundaries[gap_start + gap_len].value
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
288 = c->boundaries[gap_start].value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
289 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
290
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
291 /* Assign these back into the cache. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
292 c->gap_start = gap_start;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
293 c->gap_len = gap_len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
294 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
295
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
296
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
297 /* Insert a new boundary in cache C; it will have cache index INDEX,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
298 and have the specified POS and VALUE. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
299 static void
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
300 insert_cache_boundary (c, index, pos, value)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
301 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
302 int index;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
303 int pos, value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
304 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
305 /* index must be a valid cache index. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
306 if (index < 0 || index > c->cache_len)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
307 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
308
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
309 /* We must never want to insert something before the dummy first
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
310 boundary. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
311 if (index == 0)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
312 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
313
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
314 /* We must only be inserting things in order. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
315 if (! (BOUNDARY_POS (c, index-1) < pos
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
316 && (index == c->cache_len
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
317 || pos < BOUNDARY_POS (c, index))))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
318 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
319
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
320 /* The value must be different from the ones around it. However, we
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
321 temporarily create boundaries that establish the same value as
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
322 the subsequent boundary, so we're not going to flag that case. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
323 if (BOUNDARY_VALUE (c, index-1) == value)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
324 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
325
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
326 move_cache_gap (c, index, 1);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
327
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
328 c->boundaries[index].pos = pos - c->buffer_beg;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
329 c->boundaries[index].value = value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
330 c->gap_start++;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
331 c->gap_len--;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
332 c->cache_len++;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
333 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
334
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
335
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
336 /* Delete the i'th entry from cache C if START <= i < END. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
337
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
338 static void
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
339 delete_cache_boundaries (c, start, end)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
340 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
341 int start, end;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
342 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
343 int len = end - start;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
344
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
345 /* Gotta be in range. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
346 if (start < 0
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
347 || end > c->cache_len)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
348 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
349
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
350 /* Gotta be in order. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
351 if (start > end)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
352 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
353
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
354 /* Can't delete the dummy entry. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
355 if (start == 0
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
356 && end >= 1)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
357 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
358
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
359 /* Minimize gap motion. If we're deleting nothing, do nothing. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
360 if (len == 0)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
361 ;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
362 /* If the gap is before the region to delete, delete from the start
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
363 forward. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
364 else if (c->gap_start <= start)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
365 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
366 move_cache_gap (c, start, 0);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
367 c->gap_len += len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
368 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
369 /* If the gap is after the region to delete, delete from the end
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
370 backward. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
371 else if (end <= c->gap_start)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
372 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
373 move_cache_gap (c, end, 0);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
374 c->gap_start -= len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
375 c->gap_len += len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
376 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
377 /* If the gap is in the region to delete, just expand it. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
378 else
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
379 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
380 c->gap_start = start;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
381 c->gap_len += len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
382 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
383
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
384 c->cache_len -= len;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
385 }
49600
23a1cea22d13 Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents: 44621
diff changeset
386
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
387
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
388
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
389 /* Set the value for a region. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
390
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
391 /* Set the value in cache C for the region START..END to VALUE. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
392 static void
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
393 set_cache_region (c, start, end, value)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
394 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
395 int start, end;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
396 int value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
397 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
398 if (start > end)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
399 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
400 if (start < c->buffer_beg
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
401 || end > c->buffer_end)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
402 abort ();
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
403
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
404 /* Eliminate this case; then we can assume that start and end-1 are
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
405 both the locations of real characters in the buffer. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
406 if (start == end)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
407 return;
49600
23a1cea22d13 Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents: 44621
diff changeset
408
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
409 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
410 /* We need to make sure that there are no boundaries in the area
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
411 between start to end; the whole area will have the same value,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
412 so those boundaries will not be necessary.
49600
23a1cea22d13 Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents: 44621
diff changeset
413
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
414 Let start_ix be the cache index of the boundary governing the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
415 first character of start..end, and let end_ix be the cache
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
416 index of the earliest boundary after the last character in
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
417 start..end. (This tortured terminology is intended to answer
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
418 all the "< or <=?" sort of questions.) */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
419 int start_ix = find_cache_boundary (c, start);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
420 int end_ix = find_cache_boundary (c, end - 1) + 1;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
421
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
422 /* We must remember the value established by the last boundary
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
423 before end; if that boundary's domain stretches beyond end,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
424 we'll need to create a new boundary at end, and that boundary
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
425 must have that remembered value. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
426 int value_at_end = BOUNDARY_VALUE (c, end_ix - 1);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
427
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
428 /* Delete all boundaries strictly within start..end; this means
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
429 those whose indices are between start_ix (exclusive) and end_ix
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
430 (exclusive). */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
431 delete_cache_boundaries (c, start_ix + 1, end_ix);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
432
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
433 /* Make sure we have the right value established going in to
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
434 start..end from the left, and no unnecessary boundaries. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
435 if (BOUNDARY_POS (c, start_ix) == start)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
436 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
437 /* Is this boundary necessary? If no, remove it; if yes, set
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
438 its value. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
439 if (start_ix > 0
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
440 && BOUNDARY_VALUE (c, start_ix - 1) == value)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
441 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
442 delete_cache_boundaries (c, start_ix, start_ix + 1);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
443 start_ix--;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
444 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
445 else
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
446 SET_BOUNDARY_VALUE (c, start_ix, value);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
447 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
448 else
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
449 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
450 /* Do we need to add a new boundary here? */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
451 if (BOUNDARY_VALUE (c, start_ix) != value)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
452 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
453 insert_cache_boundary (c, start_ix + 1, start, value);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
454 start_ix++;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
455 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
456 }
49600
23a1cea22d13 Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents: 44621
diff changeset
457
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
458 /* This is equivalent to letting end_ix float (like a buffer
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
459 marker does) with the insertions and deletions we may have
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
460 done. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
461 end_ix = start_ix + 1;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
462
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
463 /* Make sure we have the correct value established as we leave
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
464 start..end to the right. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
465 if (end == c->buffer_end)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
466 /* There is no text after start..end; nothing to do. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
467 ;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
468 else if (end_ix >= c->cache_len
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
469 || end < BOUNDARY_POS (c, end_ix))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
470 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
471 /* There is no boundary at end, but we may need one. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
472 if (value_at_end != value)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
473 insert_cache_boundary (c, end_ix, end, value_at_end);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
474 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
475 else
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
476 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
477 /* There is a boundary at end; should it be there? */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
478 if (value == BOUNDARY_VALUE (c, end_ix))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
479 delete_cache_boundaries (c, end_ix, end_ix + 1);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
480 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
481 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
482 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
483
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
484
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
485
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
486 /* Interface: Invalidating the cache. Private: Re-validating the cache. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
487
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
488 /* Indicate that a section of BUF has changed, to invalidate CACHE.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
489 HEAD is the number of chars unchanged at the beginning of the buffer.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
490 TAIL is the number of chars unchanged at the end of the buffer.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
491 NOTE: this is *not* the same as the ending position of modified
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
492 region.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
493 (This way of specifying regions makes more sense than absolute
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
494 buffer positions in the presence of insertions and deletions; the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
495 args to pass are the same before and after such an operation.) */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
496 void
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
497 invalidate_region_cache (buf, c, head, tail)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
498 struct buffer *buf;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
499 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
500 int head, tail;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
501 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
502 /* Let chead = c->beg_unchanged, and
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
503 ctail = c->end_unchanged.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
504 If z-tail < beg+chead by a large amount, or
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
505 z-ctail < beg+head by a large amount,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
506
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
507 then cutting back chead and ctail to head and tail would lose a
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
508 lot of information that we could preserve by revalidating the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
509 cache before processing this invalidation. Losing that
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
510 information may be more costly than revalidating the cache now.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
511 So go ahead and call revalidate_region_cache if it seems that it
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
512 might be worthwhile. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
513 if (((BUF_BEG (buf) + c->beg_unchanged) - (BUF_Z (buf) - tail)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
514 > PRESERVE_THRESHOLD)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
515 || ((BUF_BEG (buf) + head) - (BUF_Z (buf) - c->end_unchanged)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
516 > PRESERVE_THRESHOLD))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
517 revalidate_region_cache (buf, c);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
518
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
519
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
520 if (head < c->beg_unchanged)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
521 c->beg_unchanged = head;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
522 if (tail < c->end_unchanged)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
523 c->end_unchanged = tail;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
524
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
525 /* We now know nothing about the region between the unchanged head
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
526 and the unchanged tail (call it the "modified region"), not even
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
527 its length.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
528
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
529 If the modified region has shrunk in size (deletions do this),
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
530 then the cache may now contain boundaries originally located in
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
531 text that doesn't exist any more.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
532
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
533 If the modified region has increased in size (insertions do
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
534 this), then there may now be boundaries in the modified region
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
535 whose positions are wrong.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
536
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
537 Even calling BOUNDARY_POS on boundaries still in the unchanged
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
538 head or tail may well give incorrect answers now, since
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
539 c->buffer_beg and c->buffer_end may well be wrong now. (Well,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
540 okay, c->buffer_beg never changes, so boundaries in the unchanged
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
541 head will still be okay. But it's the principle of the thing.)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
542
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
543 So things are generally a mess.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
544
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
545 But we don't clean up this mess here; that would be expensive,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
546 and this function gets called every time any buffer modification
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
547 occurs. Rather, we can clean up everything in one swell foop,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
548 accounting for all the modifications at once, by calling
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
549 revalidate_region_cache before we try to consult the cache the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
550 next time. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
551 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
552
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
553
49600
23a1cea22d13 Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents: 44621
diff changeset
554 /* Clean out any cache entries applying to the modified region, and
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
555 make the positions of the remaining entries accurate again.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
556
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
557 After calling this function, the mess described in the comment in
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
558 invalidate_region_cache is cleaned up.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
559
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
560 This function operates by simply throwing away everything it knows
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
561 about the modified region. It doesn't care exactly which
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
562 insertions and deletions took place; it just tosses it all.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
563
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
564 For example, if you insert a single character at the beginning of
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
565 the buffer, and a single character at the end of the buffer (for
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
566 example), without calling this function in between the two
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
567 insertions, then the entire cache will be freed of useful
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
568 information. On the other hand, if you do manage to call this
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
569 function in between the two insertions, then the modified regions
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
570 will be small in both cases, no information will be tossed, and the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
571 cache will know that it doesn't have knowledge of the first and
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
572 last characters any more.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
573
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
574 Calling this function may be expensive; it does binary searches in
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
575 the cache, and causes cache gap motion. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
576
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
577 static void
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
578 revalidate_region_cache (buf, c)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
579 struct buffer *buf;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
580 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
581 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
582 /* The boundaries now in the cache are expressed relative to the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
583 buffer_beg and buffer_end values stored in the cache. Now,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
584 buffer_beg and buffer_end may not be the same as BUF_BEG (buf)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
585 and BUF_Z (buf), so we have two different "bases" to deal with
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
586 --- the cache's, and the buffer's. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
587
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
588 /* If the entire buffer is still valid, don't waste time. Yes, this
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
589 should be a >, not a >=; think about what beg_unchanged and
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
590 end_unchanged get set to when the only change has been an
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
591 insertion. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
592 if (c->buffer_beg + c->beg_unchanged
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
593 > c->buffer_end - c->end_unchanged)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
594 return;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
595
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
596 /* If all the text we knew about as of the last cache revalidation
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
597 is still there, then all of the information in the cache is still
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
598 valid. Because c->buffer_beg and c->buffer_end are out-of-date,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
599 the modified region appears from the cache's point of view to be
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
600 a null region located someplace in the buffer.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
601
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
602 Now, invalidating that empty string will have no actual affect on
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
603 the cache; instead, we need to update the cache's basis first
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
604 (which will give the modified region the same size in the cache
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
605 as it has in the buffer), and then invalidate the modified
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
606 region. */
49600
23a1cea22d13 Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents: 44621
diff changeset
607 if (c->buffer_beg + c->beg_unchanged
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
608 == c->buffer_end - c->end_unchanged)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
609 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
610 /* Move the gap so that all the boundaries in the unchanged head
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
611 are expressed beg-relative, and all the boundaries in the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
612 unchanged tail are expressed end-relative. That done, we can
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
613 plug in the new buffer beg and end, and all the positions
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
614 will be accurate.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
615
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
616 The boundary which has jurisdiction over the modified region
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
617 should be left before the gap. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
618 move_cache_gap (c,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
619 (find_cache_boundary (c, (c->buffer_beg
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
620 + c->beg_unchanged))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
621 + 1),
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
622 0);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
623
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
624 c->buffer_beg = BUF_BEG (buf);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
625 c->buffer_end = BUF_Z (buf);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
626
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
627 /* Now that the cache's basis has been changed, the modified
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
628 region actually takes up some space in the cache, so we can
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
629 invalidate it. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
630 set_cache_region (c,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
631 c->buffer_beg + c->beg_unchanged,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
632 c->buffer_end - c->end_unchanged,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
633 0);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
634 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
635
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
636 /* Otherwise, there is a non-empty region in the cache which
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
637 corresponds to the modified region of the buffer. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
638 else
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
639 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
640 int modified_ix;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
641
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
642 /* These positions are correct, relative to both the cache basis
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
643 and the buffer basis. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
644 set_cache_region (c,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
645 c->buffer_beg + c->beg_unchanged,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
646 c->buffer_end - c->end_unchanged,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
647 0);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
648
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
649 /* Now the cache contains only boundaries that are in the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
650 unchanged head and tail; we've disposed of any boundaries
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
651 whose positions we can't be sure of given the information
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
652 we've saved.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
653
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
654 If we put the cache gap between the unchanged head and the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
655 unchanged tail, we can adjust all the boundary positions at
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
656 once, simply by setting buffer_beg and buffer_end.
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
657
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
658 The boundary which has jurisdiction over the modified region
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
659 should be left before the gap. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
660 modified_ix =
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
661 find_cache_boundary (c, (c->buffer_beg + c->beg_unchanged)) + 1;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
662 move_cache_gap (c, modified_ix, 0);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
663
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
664 c->buffer_beg = BUF_BEG (buf);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
665 c->buffer_end = BUF_Z (buf);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
666
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
667 /* Now, we may have shrunk the buffer when we changed the basis,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
668 and brought the boundaries we created for the start and end
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
669 of the modified region together, giving them the same
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
670 position. If that's the case, we should collapse them into
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
671 one boundary. Or we may even delete them both, if the values
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
672 before and after them are the same. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
673 if (modified_ix < c->cache_len
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
674 && (BOUNDARY_POS (c, modified_ix - 1)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
675 == BOUNDARY_POS (c, modified_ix)))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
676 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
677 int value_after = BOUNDARY_VALUE (c, modified_ix);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
678
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
679 /* Should we remove both of the boundaries? Yes, if the
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
680 latter boundary is now establishing the same value that
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
681 the former boundary's predecessor does. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
682 if (modified_ix - 1 > 0
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
683 && value_after == BOUNDARY_VALUE (c, modified_ix - 2))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
684 delete_cache_boundaries (c, modified_ix - 1, modified_ix + 1);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
685 else
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
686 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
687 /* We do need a boundary here; collapse the two
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
688 boundaries into one. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
689 SET_BOUNDARY_VALUE (c, modified_ix - 1, value_after);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
690 delete_cache_boundaries (c, modified_ix, modified_ix + 1);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
691 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
692 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
693 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
694
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
695 /* Now the entire cache is valid. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
696 c->beg_unchanged
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
697 = c->end_unchanged
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
698 = c->buffer_end - c->buffer_beg;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
699 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
700
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
701
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
702 /* Interface: Adding information to the cache. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
703
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
704 /* Assert that the region of BUF between START and END (absolute
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
705 buffer positions) is "known," for the purposes of CACHE (e.g. "has
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
706 no newlines", in the case of the line cache). */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
707 void
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
708 know_region_cache (buf, c, start, end)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
709 struct buffer *buf;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
710 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
711 int start, end;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
712 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
713 revalidate_region_cache (buf, c);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
714
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
715 set_cache_region (c, start, end, 1);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
716 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
717
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
718
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
719 /* Interface: using the cache. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
720
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
721 /* Return true if the text immediately after POS in BUF is known, for
49600
23a1cea22d13 Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents: 44621
diff changeset
722 the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest
11047
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
723 position after POS where the knownness changes. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
724 int
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
725 region_cache_forward (buf, c, pos, next)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
726 struct buffer *buf;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
727 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
728 int pos;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
729 int *next;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
730 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
731 revalidate_region_cache (buf, c);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
732
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
733 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
734 int i = find_cache_boundary (c, pos);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
735 int i_value = BOUNDARY_VALUE (c, i);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
736 int j;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
737
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
738 /* Beyond the end of the buffer is unknown, by definition. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
739 if (pos >= BUF_Z (buf))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
740 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
741 if (next) *next = BUF_Z (buf);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
742 i_value = 0;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
743 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
744 else if (next)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
745 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
746 /* Scan forward from i to find the next differing position. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
747 for (j = i + 1; j < c->cache_len; j++)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
748 if (BOUNDARY_VALUE (c, j) != i_value)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
749 break;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
750
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
751 if (j < c->cache_len)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
752 *next = BOUNDARY_POS (c, j);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
753 else
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
754 *next = BUF_Z (buf);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
755 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
756
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
757 return i_value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
758 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
759 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
760
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
761 /* Return true if the text immediately before POS in BUF is known, for
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
762 the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
763 position before POS where the knownness changes. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
764 int region_cache_backward (buf, c, pos, next)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
765 struct buffer *buf;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
766 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
767 int pos;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
768 int *next;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
769 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
770 revalidate_region_cache (buf, c);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
771
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
772 /* Before the beginning of the buffer is unknown, by
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
773 definition. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
774 if (pos <= BUF_BEG (buf))
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
775 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
776 if (next) *next = BUF_BEG (buf);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
777 return 0;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
778 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
779
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
780 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
781 int i = find_cache_boundary (c, pos - 1);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
782 int i_value = BOUNDARY_VALUE (c, i);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
783 int j;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
784
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
785 if (next)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
786 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
787 /* Scan backward from i to find the next differing position. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
788 for (j = i - 1; j >= 0; j--)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
789 if (BOUNDARY_VALUE (c, j) != i_value)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
790 break;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
791
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
792 if (j >= 0)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
793 *next = BOUNDARY_POS (c, j + 1);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
794 else
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
795 *next = BUF_BEG (buf);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
796 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
797
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
798 return i_value;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
799 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
800 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
801
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
802
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
803 /* Debugging: pretty-print a cache to the standard error output. */
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
804
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
805 void
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
806 pp_cache (c)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
807 struct region_cache *c;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
808 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
809 int i;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
810 int beg_u = c->buffer_beg + c->beg_unchanged;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
811 int end_u = c->buffer_end - c->end_unchanged;
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
812
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
813 fprintf (stderr,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
814 "basis: %d..%d modified: %d..%d\n",
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
815 c->buffer_beg, c->buffer_end,
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
816 beg_u, end_u);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
817
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
818 for (i = 0; i < c->cache_len; i++)
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
819 {
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
820 int pos = BOUNDARY_POS (c, i);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
821
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
822 putc (((pos < beg_u) ? 'v'
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
823 : (pos == beg_u) ? '-'
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
824 : ' '),
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
825 stderr);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
826 putc (((pos > end_u) ? '^'
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
827 : (pos == end_u) ? '-'
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
828 : ' '),
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
829 stderr);
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
830 fprintf (stderr, "%d : %d\n", pos, BOUNDARY_VALUE (c, i));
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
831 }
a6e2398557f6 Initial revision
Karl Heuer <kwzh@gnu.org>
parents:
diff changeset
832 }
52401
695cf19ef79e Add arch taglines
Miles Bader <miles@gnu.org>
parents: 49600
diff changeset
833
695cf19ef79e Add arch taglines
Miles Bader <miles@gnu.org>
parents: 49600
diff changeset
834 /* arch-tag: 98c29f3f-2ca2-4e3a-92f0-f2249200a17d
695cf19ef79e Add arch taglines
Miles Bader <miles@gnu.org>
parents: 49600
diff changeset
835 (do not change this comment) */