瀏覽代碼

org-element: Implement lazy cache synchronization

* lisp/org-element.el (org-element-cache-sync-idle-time): Change
  default value.
(org-element-cache-sync-duration, org-element-cache-sync-break,
org-element--cache-sync-requests, org-element--cache-sync-timer,
org-element--cache-sync-keys, org-element--cache-default-key,
org-element--cache-change-warning): New variables.
(org-element-cache-merge-changes-threshold,
org-element--cache-status): Removed variables.
(org-element--cache-key, org-element--cache-generate-key,
org-element--cache-key-less-p, org-element--cache-find,
org-element--cache-set-timer, org-element--cache-process-request,
org-element--cache-submit-request, org-element--parse-to,
org-element--cache-interrupt-p, org-element--cache-put,
org-element--cache-active-p): New functions.
(org-element--cache-compare): Adapt to new keys in AVL tree.
(org-element--cache-pending-changes-p,
org-element--cache-cancel-changes, org-element--cache-mapc,
org-element-cache-get, org-element-cache-put): Removed functions.
(org-element--cache-before-change): Use new variables.
(org-element--cache-after-change): Renamed from
`org-element--cache-record-change'.
(org-element-cache-get): Change signature.
(org-element-cache-put): Rewrite function.  Use new tools.
(org-element-cache-reset): Adapt to new variables.
(org-element--cache-sync): Rewrite function.

* lisp/ox.el (org-export--generate-copy-script): Do not copy through
  new cache-related variables.
(org-export-ignored-local-variables): New variable.

* testing/lisp/test-org-element.el (test-org-element/cache): New test.

Now only the part of the cache that needs to be accessed is updated
synchronously.  Otherwise, it happens on idle time.
Nicolas Goaziou 11 年之前
父節點
當前提交
eed0500913
共有 3 個文件被更改,包括 1120 次插入7 次删除
  1. 998 2
      lisp/org-element.el
  2. 11 5
      lisp/ox.el
  3. 111 0
      testing/lisp/test-org-element.el

File diff suppressed because it is too large
+ 998 - 2
lisp/org-element.el


+ 11 - 5
lisp/ox.el

@@ -263,6 +263,16 @@ whose extension is either \"png\", \"jpeg\", \"jpg\", \"gif\",
 See `org-export-inline-image-p' for more information about
 rules.")
 
+(defconst org-export-ignored-local-variables
+  '(org-font-lock-keywords
+    org-element--cache org-element--cache-objects org-element--cache-sync-keys
+    org-element--cache-sync-requests org-element--cache-sync-timer)
+  "List of variables not copied through upon buffer duplication.
+Export process takes place on a copy of the original buffer.
+When this copy is created, all Org related local variables not in
+this list are copied to the new buffer.  Variables with an
+unreadable value are also ignored.")
+
 (defvar org-export-async-debug nil
   "Non-nil means asynchronous export process should leave data behind.
 
@@ -2964,11 +2974,7 @@ The function assumes BUFFER's major mode is `org-mode'."
 	       (when (consp entry)
 		 (let ((var (car entry))
 		       (val (cdr entry)))
-		   (and (not (memq var '(org-font-lock-keywords
-					 ;; Do not share cache across
-					 ;; buffers as values are
-					 ;; modified by side effect.
-					 org-element--cache)))
+		   (and (not (memq var org-export-ignored-local-variables))
 			(or (memq var
 				  '(default-directory
 				     buffer-file-name

+ 111 - 0
testing/lisp/test-org-element.el

@@ -3036,5 +3036,116 @@ Paragraph \\alpha."
 	   (org-element-type (org-element-context (org-element-at-point))))))))
 
 
+
+;;; Test Cache.
+
+(ert-deftest test-org-element/cache ()
+  "Test basic expectations and common pitfalls for cache."
+  ;; Shift positions.
+  (should
+   (equal '(18 . 23)
+	  (org-test-with-temp-text "para1\n\npara2\n\npara3"
+	    (let ((org-element-use-cache t))
+	      (save-excursion (goto-char (point-max)) (org-element-at-point))
+	      (insert "add")
+	      (forward-line 4)
+	      (let ((element (org-element-at-point)))
+		(cons (org-element-property :begin element)
+		      (org-element-property :end element)))))))
+  ;; Partial shifting: when the contents of a greater element are
+  ;; modified, only shift ending positions.
+  (should
+   (org-test-with-temp-text
+       "#+BEGIN_CENTER\nPara1\n\nPara2\n\nPara3\n#+END_CENTER"
+     (let ((org-element-use-cache t))
+       (save-excursion (search-forward "3") (org-element-at-point))
+       (search-forward "Para2")
+       (insert " ")
+       (let ((element (org-element-property :parent (org-element-at-point))))
+	 (equal (cons (org-element-property :begin element)
+		      (org-element-property :end element))
+		(cons (point-min) (point-max)))))))
+  ;; Re-parent shifted elements.
+  (should
+   (eq 'item
+       (org-test-with-temp-text "- item\n\n\n  para1\n  para2"
+	 (let ((org-element-use-cache t))
+	   (end-of-line)
+	   (org-element-at-point)
+	   (save-excursion (goto-char (point-max)) (org-element-at-point))
+	   (forward-line)
+	   (delete-char 1)
+	   (goto-char (point-max))
+	   (org-element-type
+	    (org-element-property :parent (org-element-at-point)))))))
+  ;; Modifying the last line of an element alters the element below.
+  (should
+   (org-test-with-temp-text "para1\n\npara2"
+     (let ((org-element-use-cache t))
+       (goto-char (point-max))
+       (org-element-at-point)
+       (forward-line -1)
+       (insert "merge")
+       (let ((element (org-element-at-point)))
+	 (equal (cons (org-element-property :begin element)
+		      (org-element-property :end element))
+		(cons (point-min) (point-max)))))))
+  ;; Modifying the first line of an element alters the element above.
+  (should
+   (org-test-with-temp-text ": fixed-width\n:not-fixed-width"
+     (let ((org-element-use-cache t))
+       (goto-char (point-max))
+       (org-element-at-point)
+       (search-backward ":")
+       (forward-char)
+       (insert " ")
+       (let ((element (org-element-at-point)))
+	 (equal (cons (org-element-property :begin element)
+		      (org-element-property :end element))
+		(cons (point-min) (point-max)))))))
+  ;; Sensitive change: adding a line alters document structure both
+  ;; above and below.
+  (should
+   (eq 'example-block
+       (org-test-with-temp-text "#+BEGIN_EXAMPLE\nPara1\n\nPara2\n"
+	 (let ((org-element-use-cache t))
+	   (goto-char (point-max))
+	   (org-element-at-point)
+	   (insert "#+END_EXAMPLE")
+	   (search-backward "Para1")
+	   (org-element-type (org-element-at-point))))))
+  (should
+   (eq 'example-block
+       (org-test-with-temp-text "Para1\n\nPara2\n#+END_EXAMPLE"
+	 (let ((org-element-use-cache t))
+	   (save-excursion (goto-char (point-max)) (org-element-at-point))
+	   (insert "#+BEGIN_EXAMPLE\n")
+	   (search-forward "Para2")
+	   (org-element-type (org-element-at-point))))))
+  ;; Sensitive change: removing a line alters document structure both
+  ;; above and below.
+  (should
+   (eq 'example-block
+       (org-test-with-temp-text
+	   "# +BEGIN_EXAMPLE\nPara1\n\nPara2\n#+END_EXAMPLE"
+	 (let ((org-element-use-cache t))
+	   (save-excursion (goto-char (point-max)) (org-element-at-point))
+	   (forward-char)
+	   (delete-char 1)
+	   (search-forward "Para2")
+	   (org-element-type (org-element-at-point))))))
+  (should
+   (eq 'example-block
+       (org-test-with-temp-text
+	   "#+BEGIN_EXAMPLE\nPara1\n\nPara2\n# +END_EXAMPLE"
+	 (let ((org-element-use-cache t))
+	   (save-excursion (goto-char (point-max)) (org-element-at-point))
+	   (search-forward "# ")
+	   (delete-char -1)
+	   (search-backward "Para1")
+	   (org-element-type (org-element-at-point)))))))
+
+
 (provide 'test-org-element)
+
 ;;; test-org-element.el ends here

Some files were not shown because too many files changed in this diff