[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] trunk r116775: Fix bug #16830 with slow search for newline
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] trunk r116775: Fix bug #16830 with slow search for newlines in forward-line. |
Date: |
Sun, 16 Mar 2014 16:29:53 +0000 |
User-agent: |
Bazaar (2.6b2) |
------------------------------------------------------------
revno: 116775
revision-id: address@hidden
parent: address@hidden
fixes bug: http://debbugs.gnu.org/16830
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Sun 2014-03-16 18:28:34 +0200
message:
Fix bug #16830 with slow search for newlines in forward-line.
src/search.c (find_newline): Speed up the function when using the
newline cache, by halving the number of calls to
region_cache_forward and region_cache_backward.
modified:
src/ChangeLog changelog-20091113204419-o5vbwnq5f7feedwu-1438
src/search.c search.c-20091113204419-o5vbwnq5f7feedwu-473
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog 2014-03-15 11:16:12 +0000
+++ b/src/ChangeLog 2014-03-16 16:28:34 +0000
@@ -1,3 +1,9 @@
+2014-03-16 Eli Zaretskii <address@hidden>
+
+ * search.c (find_newline): Speed up the function when using the
+ newline cache, by halving the number of call to
+ region_cache_forward and region_cache_backward. (Bug#16830)
+
2014-03-15 Juanma Barranquero <address@hidden>
* buffer.c (Fset_buffer): Document return value (bug#17015).
=== modified file 'src/search.c'
--- a/src/search.c 2014-01-01 17:44:48 +0000
+++ b/src/search.c 2014-03-16 16:28:34 +0000
@@ -715,19 +715,62 @@
examine. */
ptrdiff_t tem, ceiling_byte = end_byte - 1;
- /* If we're looking for a newline, consult the newline cache
- to see where we can avoid some scanning. */
+ /* If we're using the newline cache, consult it to see whether
+ we can avoid some scanning. */
if (newline_cache)
{
ptrdiff_t next_change;
+ int result = 1;
+
immediate_quit = 0;
- while (region_cache_forward
- (cache_buffer, newline_cache, start, &next_change))
- start = next_change;
+ while (start < end && result)
+ {
+ ptrdiff_t lim1;
+
+ result = region_cache_forward (cache_buffer, newline_cache,
+ start, &next_change);
+ if (result)
+ {
+ start = next_change;
+ lim1 = next_change = end;
+ }
+ else
+ lim1 = min (next_change, end);
+
+ /* The cache returned zero for this region; see if
+ this is because the region is known and includes
+ only newlines. While at that, count any newlines
+ we bump into, and exit if we found enough off them. */
+ start_byte = CHAR_TO_BYTE (start);
+ while (start < lim1
+ && FETCH_BYTE (start_byte) == '\n')
+ {
+ start_byte++;
+ start++;
+ if (--count == 0)
+ {
+ if (bytepos)
+ *bytepos = start_byte;
+ return start;
+ }
+ }
+ /* If we found a non-newline character before hitting
+ position where the cache will again return non-zero
+ (i.e. no newlines beyond that position), it means
+ this region is not yet known to the cache, and we
+ must resort to the "dumb loop" method. */
+ if (start < next_change && !result)
+ break;
+ result = 1;
+ }
+ if (start >= end)
+ {
+ start = end;
+ start_byte = end_byte;
+ break;
+ }
immediate_quit = allow_quit;
- start_byte = CHAR_TO_BYTE (start);
-
/* START should never be after END. */
if (start_byte > ceiling_byte)
start_byte = ceiling_byte;
@@ -762,9 +805,9 @@
unsigned char *nl = memchr (lim_addr + cursor, '\n', - cursor);
next = nl ? nl - lim_addr : 0;
- /* If we're looking for newlines, cache the fact that
- this line's region is free of them. */
- if (newline_cache)
+ /* If we're using the newline cache, cache the fact that
+ the region we just traversed is free of newlines. */
+ if (newline_cache && cursor != next)
{
know_region_cache (cache_buffer, newline_cache,
BYTE_TO_CHAR (lim_byte + cursor),
@@ -800,14 +843,47 @@
if (newline_cache)
{
ptrdiff_t next_change;
+ int result = 1;
+
immediate_quit = 0;
- while (region_cache_backward
- (cache_buffer, newline_cache, start, &next_change))
- start = next_change;
+ while (start > end && result)
+ {
+ ptrdiff_t lim1;
+
+ result = region_cache_backward (cache_buffer, newline_cache,
+ start, &next_change);
+ if (result)
+ {
+ start = next_change;
+ lim1 = next_change = end;
+ }
+ else
+ lim1 = max (next_change, end);
+ start_byte = CHAR_TO_BYTE (start);
+ while (start > lim1
+ && FETCH_BYTE (start_byte - 1) == '\n')
+ {
+ if (++count == 0)
+ {
+ if (bytepos)
+ *bytepos = start_byte;
+ return start;
+ }
+ start_byte--;
+ start--;
+ }
+ if (start > next_change && !result)
+ break;
+ result = 1;
+ }
+ if (start <= end)
+ {
+ start = end;
+ start_byte = end_byte;
+ break;
+ }
immediate_quit = allow_quit;
- start_byte = CHAR_TO_BYTE (start);
-
/* Start should never be at or before end. */
if (start_byte <= ceiling_byte)
start_byte = ceiling_byte + 1;
@@ -840,7 +916,7 @@
/* If we're looking for newlines, cache the fact that
this line's region is free of them. */
- if (newline_cache)
+ if (newline_cache && cursor != prev + 1)
{
know_region_cache (cache_buffer, newline_cache,
BYTE_TO_CHAR (ceiling_byte + prev + 1),
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] trunk r116775: Fix bug #16830 with slow search for newlines in forward-line.,
Eli Zaretskii <=