# HG changeset patch # User Steve Losh # Date 1579925116 18000 # Node ID e3aefcbf364cb6449942981685138f329723e5ad # Parent 0a5694fe577c0ddfbd2897d76dc484eb49773f58 Cache Uniprot results on the filesystem This will make only the first `(run-tests)` on a given computer take forever, instead of the first `(run-tests)` of a given Lisp session. It will also hopefully make the Uniprot folks not hate me. diff -r 0a5694fe577c -r e3aefcbf364c src/utils.lisp --- a/src/utils.lisp Fri Jan 24 22:42:19 2020 -0500 +++ b/src/utils.lisp Fri Jan 24 23:05:16 2020 -0500 @@ -433,24 +433,43 @@ ;;;; Uniprot ------------------------------------------------------------------ -(defvar *uniprot-cache* (make-hash-table :test #'equal)) +(defparameter *cache-dir* + (_ (or (uiop:getenv "XDG_CACHE_HOME") + (format nil "~A/.cache" (uiop:getenv "HOME"))) + (string-right-trim "/" _) + (format nil "~A/sjl-rosalind/" _))) + +(defun cache-path (key) + (concatenate 'string *cache-dir* key)) + +(defun cachedp (key) + (probe-file (cache-path key))) -(defmacro get-cached (key cache expr) - (once-only (key cache) - (with-gensyms (value) - `(if-found (,value (gethash ,key ,cache)) - ,value - (setf (gethash ,key ,cache) ,expr))))) +(defun getcache (key) + (with-open-file (s (cache-path key)) + (read s))) + +(defun setcache (key value) + (ensure-directories-exist *cache-dir*) + (let ((*print-readably* t)) + (with-open-file (s (cache-path key) :direction :output) + (print value s))) + value) + +(defmacro ensure-cached (key expr) + (once-only (key) + `(if (cachedp ,key) + (getcache ,key) + (setcache ,key ,expr)))) (defun uniprot-url (id) (format nil "http://www.uniprot.org/uniprot/~A.fasta" id)) (defun uniprot (id) - (get-cached id *uniprot-cache* - (_ (uniprot-url id) - drakma:http-request - read-fasta-into-alist - first))) + (ensure-cached id (_ (uniprot-url id) + drakma:http-request + read-fasta-into-alist + first))) ;;;; Output -------------------------------------------------------------------