]> git.eshelyaron.com Git - emacs.git/commitdiff
org-cite-list-citations: Cache footnote-definition searches
authorIhor Radchenko <yantar92@gmail.com>
Thu, 16 Jun 2022 02:43:29 +0000 (10:43 +0800)
committerEli Zaretskii <eliz@gnu.org>
Thu, 16 Jun 2022 07:55:05 +0000 (10:55 +0300)
* lisp/org/oc.el (org-cite-list-citations): Avoid quadratic complexity.
Pre-calculate list of all footnote definitions and cache the footnote
label search hits.  Do not make `org-element-map' accumulate unused
result.

lisp/org/oc.el

index eb5f519cb64df32d9c7a311c3c2af0be6f4baf8e..c4cd0268c7c0af3342818d8ef65990641a9d269a 100644 (file)
@@ -808,6 +808,8 @@ INFO is the export communication channel, as a property list."
   (or (plist-get info :citations)
       (letrec ((cites nil)
                (tree (plist-get info :parse-tree))
+               (definition-cache (make-hash-table :test #'equal))
+               (definition-list nil)
                (find-definition
                 ;; Find definition for standard reference LABEL.  At
                 ;; this point, it is impossible to rely on
@@ -816,11 +818,21 @@ INFO is the export communication channel, as a property list."
                 ;; un-processed citation objects.  So we use
                 ;; a simplified version of the function above.
                 (lambda (label)
-                  (org-element-map tree 'footnote-definition
-                    (lambda (d)
-                      (and (equal label (org-element-property :label d))
-                           (or (org-element-contents d) "")))
-                    info t)))
+                  (or (gethash label definition-cache)
+                      (org-element-map
+                          (or definition-list
+                              (setq definition-list
+                                    (org-element-map
+                                        tree
+                                        'footnote-definition
+                                      #'identity info)))
+                          'footnote-definition
+                        (lambda (d)
+                          (and (equal label (org-element-property :label d))
+                               (puthash label
+                                        (or (org-element-contents d) "")
+                                        definition-cache)))
+                        info t))))
                (search-cites
                 (lambda (data)
                   (org-element-map data '(citation footnote-reference)
@@ -834,7 +846,8 @@ INFO is the export communication channel, as a property list."
                         (_
                          (let ((label (org-element-property :label datum)))
                            (funcall search-cites
-                                    (funcall find-definition label))))))
+                                    (funcall find-definition label)))))
+                      nil)
                     info nil 'footnote-definition t))))
         (funcall search-cites tree)
         (let ((result (nreverse cites)))