Skip to content

Commit f77800c

Browse files
committed
org-persist: Avoid overwriting / re-reading unchanged persisted data
* lisp/org-persist.el (org-persist--read-cache): (org-persist--write-cache): New variables holding previously written / read data. (org-persist-read): Avoid re-reading data from FS when the writing has been performed in the same Emacs session. (org-persist-write): Do not overwrite unchanged data.
1 parent d687aa1 commit f77800c

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

lisp/org-persist.el

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,14 @@ When ASSOCIATED is `all', unregister CONTAINER everywhere."
749749
(remove container (plist-get collection :container)))
750750
(org-persist--add-to-index collection))))))
751751

752+
(defvar org-persist--read-cache (make-hash-table :test #'equal)
753+
"Hash table storing as-read data object hashes.
754+
755+
This data is used to avoid overwriting unchanged data.")
756+
(defvar org-persist--write-cache (make-hash-table :test #'equal)
757+
"Hash table storing as-written data objects.
758+
759+
This data is used to avoid reading the data multiple times.")
752760
(defun org-persist-read (container &optional associated hash-must-match load?)
753761
"Restore CONTAINER data for ASSOCIATED.
754762
When HASH-MUST-MATCH is non-nil, do not restore data if hash for
@@ -783,15 +791,18 @@ When LOAD? is non-nil, load the data instead of reading."
783791
(unless (seq-find (lambda (v)
784792
(run-hook-with-args-until-success 'org-persist-before-read-hook v associated))
785793
(plist-get collection :container))
786-
(setq data (org-persist--read-elisp-file persist-file))
787-
(cl-loop for container in (plist-get collection :container)
788-
with result = nil
789-
do
790-
(if load?
791-
(push (org-persist-load:generic container (alist-get container data nil nil #'equal) collection) result)
792-
(push (org-persist-read:generic container (alist-get container data nil nil #'equal) collection) result))
793-
(run-hook-with-args 'org-persist-after-read-hook container associated)
794-
finally return (if (= 1 (length result)) (car result) result)))))))
794+
(setq data (or (gethash persist-file org-persist--write-cache)
795+
(org-persist--read-elisp-file persist-file)))
796+
(puthash persist-file (sxhash-equal data) org-persist--read-cache)
797+
(when data
798+
(cl-loop for container in (plist-get collection :container)
799+
with result = nil
800+
do
801+
(if load?
802+
(push (org-persist-load:generic container (alist-get container data nil nil #'equal) collection) result)
803+
(push (org-persist-read:generic container (alist-get container data nil nil #'equal) collection) result))
804+
(run-hook-with-args 'org-persist-after-read-hook container associated)
805+
finally return (if (= 1 (length result)) (car result) result))))))))
795806

796807
(defun org-persist-load (container &optional associated hash-must-match)
797808
"Load CONTAINER data for ASSOCIATED.
@@ -847,7 +858,9 @@ When IGNORE-RETURN is non-nil, just return t on success without calling
847858
(let ((file (org-file-name-concat org-persist-directory (plist-get collection :persist-file)))
848859
(data (mapcar (lambda (c) (cons c (org-persist-write:generic c collection)))
849860
(plist-get collection :container))))
850-
(org-persist--write-elisp-file file data)
861+
(puthash file data org-persist--write-cache)
862+
(unless (equal (sxhash-equal data) (gethash file org-persist--read-cache))
863+
(org-persist--write-elisp-file file data))
851864
(or ignore-return (org-persist-read container associated))))))))
852865

853866
(defun org-persist-write-all (&optional associated)

0 commit comments

Comments
 (0)