From 56830c1792b548e9157cdd95f4bb7c093e390a05 Mon Sep 17 00:00:00 2001 Message-Id: <56830c1792b548e9157cdd95f4bb7c093e390a05.1655362876.git.yantar92@gmail.com> In-Reply-To: <3342137359f122ed7168dc75096c6a5d3839a0c2.1655362876.git.yantar92@gmail.com> References: <3342137359f122ed7168dc75096c6a5d3839a0c2.1655362876.git.yantar92@gmail.com> From: Ihor Radchenko Date: Thu, 16 Jun 2022 10:43:29 +0800 Subject: [PATCH 8/8] 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 eb5f519cb..c4cd0268c 100644 --- a/lisp/oc.el +++ b/lisp/oc.el @@ -808,6 +808,8 @@ (defun org-cite-list-citations (info) (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 @@ (defun org-cite-list-citations (info) ;; 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 @@ (defun org-cite-list-citations (info) (_ (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))) -- 2.35.1