[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master e7ec6a8 1/7: Implemented finder cache
From: |
Ian Dunn |
Subject: |
[elpa] master e7ec6a8 1/7: Implemented finder cache |
Date: |
Sun, 11 Nov 2018 15:04:49 -0500 (EST) |
branch: master
commit e7ec6a832f3085e1a9e3dd37388dc2c37842b181
Author: Ian Dunn <address@hidden>
Commit: Ian Dunn <address@hidden>
Implemented finder cache
* org-edna.el (org-edna--finder-input):
(org-edna--finder-cache-entry): New structs.
(org-edna-finder-use-cache): New defcustom to toggle cache.
(org-edna--finder-cache): Internal cache table.
(org-edna-finder-cache-timeout): New defcustom to control cache duration.
(org-edna--add-to-finder-cache): Internal helper function.
(org-edna--finder-cache-timeout): Placeholder function.
(org-edna--handle-finder): Handles cache for finders.
(org-edna--expand-single-sexp-form): Use new finder function.
---
org-edna.el | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 73 insertions(+), 1 deletion(-)
diff --git a/org-edna.el b/org-edna.el
index 9974e3a..5184350 100644
--- a/org-edna.el
+++ b/org-edna.el
@@ -387,7 +387,7 @@ correspond to internal variables."
(`(,type . ,func) (org-edna--function-for-key key)))
(pcase type
('finder
- `(setq ,target-var (org-edna--add-targets ,target-var (,func ,@args))))
+ `(setq ,target-var (org-edna--add-targets ,target-var
(org-edna--handle-finder ',func ',args))))
('action
`(org-edna--handle-action ',func ,target-var (point-marker) ',args))
('condition
@@ -464,6 +464,78 @@ which of the two types is allowed in STRING-FORM."
(org-edna-eval-sexp-form
(org-edna-string-form-to-sexp-form string-form action-or-condition)))
+;;; Cache
+
+;; Cache works because the returned values of finders are all markers. Markers
+;; will automatically update themselves when a buffer is edited.
+
+(cl-defstruct org-edna--finder-input
+ func-sym args)
+
+(cl-defstruct org-edna--finder-cache-entry
+ input results last-run-time)
+
+(defvar org-edna--finder-cache (make-hash-table :test 'equal))
+
+(defcustom org-edna-finder-use-cache nil
+ "Whether to use cache for improved performance with finders.
+
+When cache is used for a finder, each finder call will store its
+results for up to `org-edna-finder-cache-timeout' seconds. The
+results and input are both stored, so the same form for a given
+finder will yield the results of the previous call.
+
+If enough time has passed since the results in cache for a
+specific form were generated, the results will be regenerated and
+stored in cache.
+
+Minor changes to an Org file, such as setting properties or
+adding unrelated headlines, will be taken into account."
+ :group 'org-edna
+ :type 'boolean)
+
+(defcustom org-edna-finder-cache-timeout 300
+ "Maximum age to keep entries in cache, in seconds."
+ :group 'org-edna
+ :type 'number)
+
+(defun org-edna--add-to-finder-cache (func-sym args)
+ (let* ((results (apply func-sym args))
+ (input (make-org-edna--finder-input :func-sym func-sym
+ :args args))
+ (entry (make-org-edna--finder-cache-entry :input input
+ :results results
+ :last-run-time
(current-time))))
+ (map-put org-edna--finder-cache input entry)))
+
+(defun org-edna--finder-cache-timeout (_func-sym)
+ ;; In the future, we may want to support configurable timeouts on a
per-finder
+ ;; basis.
+ org-edna-finder-cache-timeout)
+
+(defun org-edna--handle-finder (func-sym args)
+ (if (not org-edna-finder-use-cache)
+ ;; Not using cache, so use the function directly.
+ (apply func-sym args)
+ (let* ((input (make-org-edna--finder-input :func-sym func-sym
+ :args args))
+ (entry (map-elt org-edna--finder-cache input)))
+ (cond
+ ;; If we don't have an entry, rerun and make a new one.
+ ((not entry)
+ (org-edna--add-to-finder-cache func-sym args))
+ ;; If we do have an entry, but it's timed out, then create a new one.
+ ((>= (float-time (time-subtract (current-time)
+
(org-edna--finder-cache-entry-last-run-time entry)))
+ (org-edna--finder-cache-timeout func-sym))
+ (org-edna--add-to-finder-cache func-sym args))
+ ;; If any element of the results is an invalid marker, then rerun.
+ ((seq-find (lambda (x) (not (markerp x)))
(org-edna--finder-cache-entry-results entry) nil)
+ (org-edna--add-to-finder-cache func-sym args))
+ ;; We have an entry created within the allowed interval.
+ (t
+ (org-edna--finder-cache-entry-results entry))))))
+
(defmacro org-edna-run (change-plist &rest body)
- [elpa] master updated (4ce0ed8 -> 7294b59), Ian Dunn, 2018/11/11
- [elpa] master de3f6fa 2/7: Bumped version, Ian Dunn, 2018/11/11
- [elpa] master e7ec6a8 1/7: Implemented finder cache,
Ian Dunn <=
- [elpa] master 9c48be8 3/7: Updated tests for new form expansion, Ian Dunn, 2018/11/11
- [elpa] master 26b0a6e 6/7: Added documentation about using a timeout for cache, Ian Dunn, 2018/11/11
- [elpa] master 71ee9f6 5/7: Added tests for cache, Ian Dunn, 2018/11/11
- [elpa] master e875a03 4/7: Improved contributing section in documentation, Ian Dunn, 2018/11/11
- [elpa] master 7294b59 7/7: Merge commit '26b0a6e6fb03fe4b895bb03972bbb0d80ce2e8e3', Ian Dunn, 2018/11/11