branch: externals/org commit b061e7b61c65bd676bd146bdf91d4b13b0927ebb Author: Ihor Radchenko <yanta...@gmail.com> Commit: Ihor Radchenko <yanta...@gmail.com>
org-cite-list-citations: Cache footnote-definition searches * 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. --- lisp/oc.el | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lisp/oc.el b/lisp/oc.el index 360f1fadcf..4dcb3f57c2 100644 --- a/lisp/oc.el +++ b/lisp/oc.el @@ -854,6 +854,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 @@ -862,11 +864,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) @@ -880,7 +892,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)))