emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r113713: Use region cache to speedup bidi_find_parag


From: Dmitry Antipov
Subject: [Emacs-diffs] trunk r113713: Use region cache to speedup bidi_find_paragraph_start.
Date: Tue, 06 Aug 2013 07:07:31 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 113713
revision-id: address@hidden
parent: address@hidden
committer: Dmitry Antipov <address@hidden>
branch nick: trunk
timestamp: Tue 2013-08-06 10:53:09 +0400
message:
  Use region cache to speedup bidi_find_paragraph_start.
  * src/buffer.h (struct buffer): New member bidi_paragraph_cache.
  Rename cache_long_line_scans to cache_long_scans.
  * src/buffer.c (bset_cache_long_line_scans): Rename to
  bset_cache_long_scans.
  (Fget_buffer_create, Fmake_indirect_buffer, Fkill_buffer)
  (Fbuffer_swap_text, init_buffer_once): Take bidi_paragraph_cache
  into account.
  (syms_of_buffer): Rename cache-long-line-scans to
  cache-long-scans.  Adjust docstring.
  * src/search.c (newline_cache_on_off):
  * src/indent.c (width_run_cache_on_off): Adjust users.
  * src/bidi.c (bidi_paragraph_cache_on_off): New function.
  (bidi_find_paragraph_start): Use bidi_paragraph_cache if needed.
  * src/insdel.c (prepare_to_modify_buffer): Invalidate
  bidi_paragraph_cache if enabled.
  * doc/lispref/positions.texi (Motion by Screen Lines):
  * doc/lispref/display.texi (Truncation): Rename `cache-long-line-scans'
  to `cache-long-scans'.
modified:
  doc/lispref/ChangeLog          changelog-20091113204419-o5vbwnq5f7feedwu-6155
  doc/lispref/display.texi       
display.texi-20091113204419-o5vbwnq5f7feedwu-6172
  doc/lispref/positions.texi     
positions.texi-20091113204419-o5vbwnq5f7feedwu-6206
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/bidi.c                     bidi.c-20091231194348-rm8gzug639w0dpq5-1
  src/buffer.c                   buffer.c-20091113204419-o5vbwnq5f7feedwu-264
  src/buffer.h                   buffer.h-20091113204419-o5vbwnq5f7feedwu-196
  src/indent.c                   indent.c-20091113204419-o5vbwnq5f7feedwu-181
  src/insdel.c                   insdel.c-20091113204419-o5vbwnq5f7feedwu-175
  src/search.c                   search.c-20091113204419-o5vbwnq5f7feedwu-473
=== modified file 'doc/lispref/ChangeLog'
--- a/doc/lispref/ChangeLog     2013-08-05 11:37:47 +0000
+++ b/doc/lispref/ChangeLog     2013-08-06 06:53:09 +0000
@@ -1,3 +1,9 @@
+2013-08-06  Dmitry Antipov  <address@hidden>
+
+       * positions.texi (Motion by Screen Lines):
+       * display.texi (Truncation): Rename `cache-long-line-scans'
+       to `cache-long-scans'.
+
 2013-08-05  Xue Fuqiao  <address@hidden>
 
        * windows.texi (Window Start and End): Add an index.

=== modified file 'doc/lispref/display.texi'
--- a/doc/lispref/display.texi  2013-08-02 13:52:10 +0000
+++ b/doc/lispref/display.texi  2013-08-06 06:53:09 +0000
@@ -217,9 +217,9 @@
 continuation to display them, computing the continuation lines can
 make redisplay slow.  The column computation and indentation functions
 also become slow.  Then you might find it advisable to set
address@hidden to @code{t}.
address@hidden to @code{t}.
 
address@hidden cache-long-line-scans
address@hidden cache-long-scans
 If this variable is address@hidden, various indentation and motion
 functions, and Emacs redisplay, cache the results of scanning the
 buffer, and consult the cache to avoid rescanning regions of the buffer

=== modified file 'doc/lispref/positions.texi'
--- a/doc/lispref/positions.texi        2013-01-01 09:11:05 +0000
+++ b/doc/lispref/positions.texi        2013-08-06 06:53:09 +0000
@@ -483,7 +483,7 @@
   These functions scan text to determine where screen lines break, and
 thus take time proportional to the distance scanned.  If you intend to
 use them heavily, Emacs provides caches which may improve the
-performance of your code.  @xref{Truncation, cache-long-line-scans}.
+performance of your code.  @xref{Truncation, cache-long-scans}.
 
 @defun vertical-motion count &optional window
 This function moves point to the start of the screen line @var{count}

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-08-06 05:30:18 +0000
+++ b/src/ChangeLog     2013-08-06 06:53:09 +0000
@@ -1,5 +1,24 @@
 2013-08-06  Dmitry Antipov  <address@hidden>
 
+       Use region cache to speedup bidi_find_paragraph_start.
+       * buffer.h (struct buffer): New member bidi_paragraph_cache.
+       Rename cache_long_line_scans to cache_long_scans.
+       * buffer.c (bset_cache_long_line_scans): Rename to
+       bset_cache_long_scans.
+       (Fget_buffer_create, Fmake_indirect_buffer, Fkill_buffer)
+       (Fbuffer_swap_text, init_buffer_once): Take bidi_paragraph_cache
+       into account.
+       (syms_of_buffer): Rename cache-long-line-scans to
+       cache-long-scans.  Adjust docstring.
+       * search.c (newline_cache_on_off):
+       * indent.c (width_run_cache_on_off): Adjust users.
+       * bidi.c (bidi_paragraph_cache_on_off): New function.
+       (bidi_find_paragraph_start): Use bidi_paragraph_cache if needed.
+       * insdel.c (prepare_to_modify_buffer): Invalidate
+       bidi_paragraph_cache if enabled.
+
+2013-08-06  Dmitry Antipov  <address@hidden>
+
        Invalidate region caches only if buffer text is going to be changed.
        * lisp.h (modify_region_1): Remove 3rd arg and rename to...
        (modify_text): ...new prototype.

=== modified file 'src/bidi.c'
--- a/src/bidi.c        2013-06-08 18:28:36 +0000
+++ b/src/bidi.c        2013-08-06 06:53:09 +0000
@@ -61,6 +61,7 @@
 #include "character.h"
 #include "buffer.h"
 #include "dispextern.h"
+#include "region-cache.h"
 
 static bool bidi_initialized = 0;
 
@@ -1085,6 +1086,29 @@
   return val;
 }
 
+/* If the user has requested the long scans caching, make sure that
+   BIDI cache is enabled.  Otherwise, make sure it's disabled.  */
+
+static struct region_cache *
+bidi_paragraph_cache_on_off (void)
+{
+  if (NILP (BVAR (current_buffer, cache_long_scans)))
+    {
+      if (current_buffer->bidi_paragraph_cache)
+       {
+         free_region_cache (current_buffer->bidi_paragraph_cache);
+         current_buffer->bidi_paragraph_cache = 0;
+       }
+      return NULL;
+    }
+  else
+    {
+      if (!current_buffer->bidi_paragraph_cache)
+       current_buffer->bidi_paragraph_cache = new_region_cache ();
+      return current_buffer->bidi_paragraph_cache;
+    }
+}
+
 /* On my 2005-vintage machine, searching back for paragraph start
    takes ~1 ms per line.  And bidi_paragraph_init is called 4 times
    when user types C-p.  The number below limits each call to
@@ -1100,7 +1124,8 @@
 {
   Lisp_Object re = paragraph_start_re;
   ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
-  ptrdiff_t n = 0;
+  struct region_cache *bpc = bidi_paragraph_cache_on_off ();
+  ptrdiff_t n = 0, oldpos = pos, next;
 
   while (pos_byte > BEGV_BYTE
         && n++ < MAX_PARAGRAPH_SEARCH
@@ -1111,10 +1136,18 @@
         of the text over which we scan back includes
         paragraph_start_re?  */
       DEC_BOTH (pos, pos_byte);
-      pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
+      if (bpc && region_cache_backward (current_buffer, bpc, pos, &next))
+       {
+         pos = next, pos_byte = CHAR_TO_BYTE (pos);
+         break;
+       }
+      else
+       pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
     }
   if (n >= MAX_PARAGRAPH_SEARCH)
-    pos_byte = BEGV_BYTE;
+    pos = BEGV, pos_byte = BEGV_BYTE;
+  if (bpc)
+    know_region_cache (current_buffer, bpc, pos, oldpos);
   return pos_byte;
 }
 

=== modified file 'src/buffer.c'
--- a/src/buffer.c      2013-08-05 04:14:43 +0000
+++ b/src/buffer.c      2013-08-06 06:53:09 +0000
@@ -203,9 +203,9 @@
   b->INTERNAL_FIELD (buffer_file_coding_system) = val;
 }
 static void
-bset_cache_long_line_scans (struct buffer *b, Lisp_Object val)
+bset_cache_long_scans (struct buffer *b, Lisp_Object val)
 {
-  b->INTERNAL_FIELD (cache_long_line_scans) = val;
+  b->INTERNAL_FIELD (cache_long_scans) = val;
 }
 static void
 bset_case_fold_search (struct buffer *b, Lisp_Object val)
@@ -583,6 +583,7 @@
 
   b->newline_cache = 0;
   b->width_run_cache = 0;
+  b->bidi_paragraph_cache = 0;
   bset_width_table (b, Qnil);
   b->prevent_redisplay_optimizations_p = 1;
 
@@ -806,6 +807,7 @@
 
   b->newline_cache = 0;
   b->width_run_cache = 0;
+  b->bidi_paragraph_cache = 0;
   bset_width_table (b, Qnil);
 
   name = Fcopy_sequence (name);
@@ -1945,6 +1947,11 @@
       free_region_cache (b->width_run_cache);
       b->width_run_cache = 0;
     }
+  if (b->bidi_paragraph_cache)
+    {
+      free_region_cache (b->bidi_paragraph_cache);
+      b->bidi_paragraph_cache = 0;
+    }
   bset_width_table (b, Qnil);
   unblock_input ();
   bset_undo_list (b, Qnil);
@@ -2355,6 +2362,7 @@
   current_buffer->clip_changed = 1;    other_buffer->clip_changed = 1;
   swapfield (newline_cache, struct region_cache *);
   swapfield (width_run_cache, struct region_cache *);
+  swapfield (bidi_paragraph_cache, struct region_cache *);
   current_buffer->prevent_redisplay_optimizations_p = 1;
   other_buffer->prevent_redisplay_optimizations_p = 1;
   swapfield (overlays_before, struct Lisp_Overlay *);
@@ -5169,7 +5177,7 @@
   bset_buffer_file_coding_system (&buffer_defaults, Qnil);
   XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70);
   XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0);
-  bset_cache_long_line_scans (&buffer_defaults, Qnil);
+  bset_cache_long_scans (&buffer_defaults, Qnil);
   bset_file_truename (&buffer_defaults, Qnil);
   XSETFASTINT (BVAR (&buffer_defaults, display_count), 0);
   XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0);
@@ -5233,7 +5241,7 @@
   XSETFASTINT (BVAR (&buffer_local_flags, abbrev_table), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx;
-  XSETFASTINT (BVAR (&buffer_local_flags, cache_long_line_scans), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, cache_long_scans), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); 
++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); 
++idx;
@@ -6120,8 +6128,8 @@
   DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil,
                     doc: /* Non-nil means the mark and region are currently 
active in this buffer.  */);
 
-  DEFVAR_PER_BUFFER ("cache-long-line-scans", &BVAR (current_buffer, 
cache_long_line_scans), Qnil,
-                    doc: /* Non-nil means that Emacs should use caches to 
handle long lines more quickly.
+  DEFVAR_PER_BUFFER ("cache-long-scans", &BVAR (current_buffer, 
cache_long_scans), Qnil,
+                    doc: /* Non-nil means that Emacs should use caches in 
attempt to speedup buffer scans.
 
 Normally, the line-motion functions work by scanning the buffer for
 newlines.  Columnar operations (like `move-to-column' and
@@ -6131,18 +6139,24 @@
 motion functions will take longer to execute.  Emacs may also take
 longer to update the display.
 
-If `cache-long-line-scans' is non-nil, these motion functions cache the
+If `cache-long-scans' is non-nil, these motion functions cache the
 results of their scans, and consult the cache to avoid rescanning
 regions of the buffer until the text is modified.  The caches are most
 beneficial when they prevent the most searching---that is, when the
 buffer contains long lines and large regions of characters with the
 same, fixed screen width.
 
-When `cache-long-line-scans' is non-nil, processing short lines will
+When `cache-long-scans' is non-nil, processing short lines will
 become slightly slower (because of the overhead of consulting the
 cache), and the caches will use memory roughly proportional to the
 number of newlines and characters whose screen width varies.
 
+Bidirectional editing also requires buffer scans to find paragraph
+separators.  If you have large paragraphs or no paragraph separators
+at all, these scans may be slow.  If `cache-long-scans' is non-nil,
+results of these scans are cached.  This doesn't help too much if
+paragraphs are of the reasonable (few thousands of characters) size.
+
 The caches require no explicit maintenance; their accuracy is
 maintained internally by the Emacs primitives.  Enabling or disabling
 the cache should not affect the behavior of any of the motion

=== modified file 'src/buffer.h'
--- a/src/buffer.h      2013-08-05 04:14:43 +0000
+++ b/src/buffer.h      2013-08-06 06:53:09 +0000
@@ -632,9 +632,9 @@
   /* List of symbols naming the file format used for auto-save file.  */
   Lisp_Object INTERNAL_FIELD (auto_save_file_format);
 
-  /* True if the newline position cache and width run cache are
-     enabled.  See search.c and indent.c.  */
-  Lisp_Object INTERNAL_FIELD (cache_long_line_scans);
+  /* True if the newline position cache, width run cache and BIDI paragraph
+     cache are enabled.  See search.c, indent.c and bidi.c for details.  */
+  Lisp_Object INTERNAL_FIELD (cache_long_scans);
 
   /* If the width run cache is enabled, this table contains the
      character widths width_run_cache (see above) assumes.  When we
@@ -839,9 +839,12 @@
      the character's width; if it maps a character to zero, we don't
      know what its width is.  This allows compute_motion to process
      such regions very quickly, using algebra instead of inspecting
-     each character.   See also width_table, below.  */
+     each character.   See also width_table, below.
+
+     The latter cache is used to speedup bidi_find_paragraph_start.  */
   struct region_cache *newline_cache;
   struct region_cache *width_run_cache;
+  struct region_cache *bidi_paragraph_cache;
 
   /* Non-zero means don't use redisplay optimizations for
      displaying this buffer.  */

=== modified file 'src/indent.c'
--- a/src/indent.c      2013-04-13 08:54:02 +0000
+++ b/src/indent.c      2013-08-06 06:53:09 +0000
@@ -141,13 +141,13 @@
     XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
 }
 
-/* Allocate or free the width run cache, as requested by the current
-   state of current_buffer's cache_long_line_scans variable.  */
+/* Allocate or free the width run cache, as requested by the
+   current state of current_buffer's cache_long_scans variable.  */
 
 static void
 width_run_cache_on_off (void)
 {
-  if (NILP (BVAR (current_buffer, cache_long_line_scans))
+  if (NILP (BVAR (current_buffer, cache_long_scans))
       /* And, for the moment, this feature doesn't work on multibyte
          characters.  */
       || !NILP (BVAR (current_buffer, enable_multibyte_characters)))

=== modified file 'src/insdel.c'
--- a/src/insdel.c      2013-08-06 05:30:18 +0000
+++ b/src/insdel.c      2013-08-06 06:53:09 +0000
@@ -1879,6 +1879,10 @@
     invalidate_region_cache (current_buffer,
                              current_buffer->width_run_cache,
                              start - BEG, Z - end);
+  if (current_buffer->bidi_paragraph_cache)
+    invalidate_region_cache (current_buffer,
+                             current_buffer->bidi_paragraph_cache,
+                             start - BEG, Z - end);
 }
 
 /* These macros work with an argument named `preserve_ptr'

=== modified file 'src/search.c'
--- a/src/search.c      2013-07-16 21:35:45 +0000
+++ b/src/search.c      2013-08-06 06:53:09 +0000
@@ -598,14 +598,14 @@
 
 /* The newline cache: remembering which sections of text have no newlines.  */
 
-/* If the user has requested newline caching, make sure it's on.
+/* If the user has requested the long scans caching, make sure it's on.
    Otherwise, make sure it's off.
    This is our cheezy way of associating an action with the change of
    state of a buffer-local variable.  */
 static void
 newline_cache_on_off (struct buffer *buf)
 {
-  if (NILP (BVAR (buf, cache_long_line_scans)))
+  if (NILP (BVAR (buf, cache_long_scans)))
     {
       /* It should be off.  */
       if (buf->newline_cache)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]