Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
2.5 KiB

  1. ;;; cache-table.el --- a hash table with expiring entries -*- lexical-binding: t; -*-
  2. ;; This is free and unencumbered software released into the public domain.
  3. ;; Author: Christopher Wellons <mosquitopsu@gmail.com>
  4. ;; Version: 1.0
  5. ;;; Commentary:
  6. ;; See the docstring of `cache-table-create'. There is no
  7. ;; `cache-table-put': use `setf' on `cache-table-get' instead.
  8. ;;; Code:
  9. (require 'cl-lib)
  10. (cl-defstruct (cache-table (:constructor cache-table--create))
  11. "A cache table with expiring entries."
  12. expire-time table)
  13. (defun cache-table-create (expire-time &rest keyword-args)
  14. "Create a new cache-table with entries automatically removed
  15. from the table after EXPIRE-TIME seconds. This function accepts
  16. the same keyword arguments as `make-hash-table'. Entries are not
  17. actually removed from the cache-table until an access is made to
  18. the cache-table.
  19. Use `cache-table-get' to get and put (via setf) entries."
  20. (cache-table--create :expire-time expire-time
  21. :table (apply #'make-hash-table keyword-args)))
  22. (defun cache-table-clear-expired (cache-table)
  23. "Remove all expired entries from CACHE-TABLE."
  24. (cl-loop with expire-time = (cache-table-expire-time cache-table)
  25. with table = (cache-table-table cache-table)
  26. with dead-time = (- (float-time) expire-time)
  27. for key being the hash-keys of table using (hash-value entry)
  28. for (time . value) = entry
  29. when (< time dead-time) do (remhash key table)))
  30. (defun cache-table-get (key cache-table &optional default)
  31. "Access the value for KEY in CACHE-TABLE if it has not yet
  32. expired. Behaves just like `gethash'."
  33. (cache-table-clear-expired cache-table)
  34. (cdr (gethash key (cache-table-table cache-table) (cons 0 default))))
  35. (gv-define-setter cache-table-get (value key cache-table)
  36. "Put an entry in the hash table, like (setf (gethash key table) value)."
  37. `(progn
  38. (cache-table-clear-expired ,cache-table)
  39. (puthash ,key (cons (float-time) ,value)
  40. (cache-table-table ,cache-table))))
  41. (defun cache-table-map (f cache-table)
  42. "Like `maphash', call F for all non-expired entries in CACHE-TABLE."
  43. (cache-table-clear-expired cache-table)
  44. (maphash (lambda (k v) (funcall f k (cdr v)))
  45. (cache-table-table cache-table)))
  46. (defun cache-table-count (cache-table)
  47. "Like `hash-table-count', count the number of non-expired entries."
  48. (hash-table-count (cache-table-table cache-table)))
  49. (provide 'cache-table)
  50. ;;; cache-table.el ends here