annotate src/region-cache.c @ 24841:d2d412758428

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