Procházet zdrojové kódy

Backport commit f94e93a6e from Emacs

* lisp/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.

org-cite-list-citations: Cache footnote-definition searches
f94e93a6eec92d834a6b545d8d4b68280b0993b0
Ihor Radchenko
Thu Jun 16 10:55:05 2022 +0300

[ km: This ported commit comes from main's b061e7b61.  I'm applying it
  here too for bookkeeping/traceability purposes.  ]
Ihor Radchenko před 2 roky
rodič
revize
c77692e8fb
1 změnil soubory, kde provedl 19 přidání a 6 odebrání
  1. 19 6
      lisp/oc.el

+ 19 - 6
lisp/oc.el

@@ -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)))