From: Andreas Gerler Date: Thu, 11 May 2023 16:13:45 +0000 (+0200) Subject: add pcache X-Git-Url: http://git.bundesbrandschatzamt.de/?a=commitdiff_plain;h=ec73c63d1c6797475d9200863ffbb5c8af852279;p=emacsconfig.git add pcache Signed-off-by: Andreas Gerler --- diff --git a/elpa/pcache-20220724.1841/pcache-autoloads.el b/elpa/pcache-20220724.1841/pcache-autoloads.el new file mode 100644 index 00000000..b72fed2e --- /dev/null +++ b/elpa/pcache-20220724.1841/pcache-autoloads.el @@ -0,0 +1,22 @@ +;;; pcache-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*- +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "pcache" "pcache.el" (0 0 0 0)) +;;; Generated autoloads from pcache.el + +(register-definition-prefixes "pcache" '("*pcache-repositor" "pcache-")) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; pcache-autoloads.el ends here diff --git a/elpa/pcache-20220724.1841/pcache-pkg.el b/elpa/pcache-20220724.1841/pcache-pkg.el new file mode 100644 index 00000000..691ed0e6 --- /dev/null +++ b/elpa/pcache-20220724.1841/pcache-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from pcache.el -*- no-byte-compile: t -*- +(define-package "pcache" "20220724.1841" "persistent caching for Emacs." '((emacs "25.1")) :commit "cae29ddbc3d12fac18ab5cfc26fa3ef13eb97dad" :authors '(("Yann Hodique" . "yann.hodique@gmail.com")) :maintainer '("Yann Hodique" . "yann.hodique@gmail.com") :keywords '("extensions")) diff --git a/elpa/pcache-20220724.1841/pcache.el b/elpa/pcache-20220724.1841/pcache.el new file mode 100644 index 00000000..209cdb18 --- /dev/null +++ b/elpa/pcache-20220724.1841/pcache.el @@ -0,0 +1,262 @@ +;;; pcache.el --- persistent caching for Emacs. -*- lexical-binding: t; -*- + +;; Copyright (C) 2011-2020 Yann Hodique + +;; Author: Yann Hodique +;; Keywords: extensions +;; Package-Version: 20220724.1841 +;; Package-Commit: cae29ddbc3d12fac18ab5cfc26fa3ef13eb97dad +;; Version: 0.5.1 +;; Package-Requires: ((emacs "25.1")) + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; pcache provides a persistent way of caching data, in a hashtable-like +;; structure. It relies on `eieio-persistent' in the backend, so that any +;; object that can be serialized by EIEIO can be stored with pcache. + +;; pcache handles objects called "repositories" (`pcache-repository') and +;; "entries" (`pcache-entry'). Each repository is identified by a unique name, +;; that defines an entry in `pcache-directory'. Subdirectories are allowed, by +;; the use of a directory separator in the repository name. + +;; Example: +;; (let ((repo (pcache-repository "plop"))) +;; (pcache-put repo 'foo 42) ; store value 42 with key 'foo +;; (pcache-get repo 'foo) ; => 42 +;; ) + +;; Keys can be pretty much any Lisp object, and are compared for equality using +;; `eql' + +;; Optionally, cache entries can expire: +;; (let ((repo (pcache-repository "plop"))) +;; (pcache-put repo 'foo 42 1) ; store value 42 with key 'foo for 1 second +;; (sleep-for 1) +;; (pcache-get repo 'foo) ; => nil +;; ) + +;;; Code: + +(require 'cl-lib) +(require 'cl-extra) +(require 'eieio) +(require 'eieio-base) + +(defvar pcache-directory (concat user-emacs-directory "var/pcache/")) + +(defvar *pcache-repositories* (make-hash-table :test 'equal)) + +(defvar pcache-avoid-recursion nil) + +(defconst pcache-default-save-delay 300) + +(defconst pcache-internal-version-constant "0.5") + +(defconst pcache-version-constant + (format "%s/%s" emacs-version pcache-internal-version-constant)) + +(defclass pcache-repository (eieio-persistent eieio-named) + ((version :initarg :version :initform nil) + (version-constant :allocation :class) + (entries :initarg :entries :initform (make-hash-table)) + (entry-cls :initarg :entry-cls :initform pcache-entry) + (timestamp :initarg :timestamp :initform (float-time (current-time))) + (save-delay :initarg :save-delay))) + +(oset-default 'pcache-repository :save-delay pcache-default-save-delay) +(oset-default 'pcache-repository version-constant pcache-version-constant) + +(defvar *pcache-repository-name* nil) + +(cl-defmethod make-instance ((cls (subclass pcache-repository)) &rest args) + (let* ((newname (or (and (stringp (car args)) (car args)) + (plist-get args :object-name) + *pcache-repository-name* + (symbol-name cls))) + (e (gethash newname *pcache-repositories*)) + (path (concat pcache-directory newname))) + (setq args (append args (list :object-name newname))) + (or e + (and (not pcache-avoid-recursion) + (file-exists-p path) + (condition-case nil + (let* ((pcache-avoid-recursion t) + (*pcache-repository-name* newname) + (obj (eieio-persistent-read path 'pcache-repository t))) + (and (or (pcache-validate-repo obj) + (error "wrong version")) + (puthash newname obj *pcache-repositories*) + obj)) + (error nil))) + (let ((obj (cl-call-next-method)) + (dir (file-name-directory path))) + (unless (file-exists-p dir) + (make-directory dir t)) + (oset obj :file path) + (oset obj :version (oref-default obj version-constant)) + (puthash newname obj *pcache-repositories*) + obj)))) + +(defun pcache-hash-table-values (h) + (let (values) + (maphash (lambda (k v) (push v values)) h) + values)) + +;; force custom implementation. +(cl-defmethod pcache-validate-repo ((cache t)) + nil) + +(cl-defmethod pcache-validate-repo ((cache pcache-repository)) + (and + (equal (oref cache version) + (oref-default (eieio-object-class cache) version-constant)) + (hash-table-p (oref cache entries)) + (cl-every + (function + (lambda (entry) + (and (object-of-class-p entry (oref cache entry-cls)) + (pcache-validate-entry entry)))) + (pcache-hash-table-values (oref cache entries))))) + +(defclass pcache-entry () + ((timestamp :initarg :timestamp + :initform (float-time (current-time))) + (ttl :initarg :ttl :initform nil) + (value :initarg :value :initform nil) + (value-cls :initarg :value-cls :initform nil))) + +;; force custom implementation. +(cl-defmethod pcache-validate-entry ((entry t)) + nil) + +(cl-defmethod pcache-validate-entry ((entry pcache-entry)) + (or (null (oref entry value-cls)) + (object-of-class-p + (oref entry value) (oref entry value-cls)))) + +(cl-defmethod pcache-entry-valid-p ((entry pcache-entry)) + (let ((ttl (oref entry ttl))) + (or (null ttl) + (let ((time (float-time (current-time)))) + (< time (+ ttl (oref entry timestamp))))))) + +(cl-defmethod pcache-get ((cache pcache-repository) key &optional default) + (let* ((table (oref cache entries)) + (entry (gethash key table))) + (if entry + (if (pcache-entry-valid-p entry) + (oref entry value) + (remhash key table) + default) + default))) + +(cl-defmethod pcache-has ((cache pcache-repository) key) + (let* ((default (make-symbol ":nil")) + (table (oref cache entries)) + (entry (gethash key table default))) + (if (eq entry default) nil + (if (pcache-entry-valid-p entry) + t nil)))) + +(cl-defmethod pcache-put ((cache pcache-repository) key value &optional ttl) + (let ((table (oref cache entries)) + (entry (or (and (eieio-object-p value) + (object-of-class-p value 'pcache-entry) + value) + (make-instance + (oref cache entry-cls) + :value value + :value-cls (and (eieio-object-p value) (eieio-object-class value)))))) + (when ttl + (oset entry :ttl ttl)) + (prog1 + (puthash key entry table) + (pcache-save cache)))) + +(cl-defmethod pcache-invalidate ((cache pcache-repository) key) + (let ((table (oref cache entries))) + (remhash key table) + (pcache-save cache))) + +(cl-defmethod pcache-clear ((cache pcache-repository)) + (let* ((entries (oref cache entries)) + (test (hash-table-test entries)) + (resize (hash-table-rehash-size entries)) + (threshold (hash-table-rehash-threshold entries)) + (weakness (hash-table-weakness entries))) + (oset cache :entries (make-hash-table :test test :rehash-size resize + :rehash-threshold threshold + :weakness weakness))) + (pcache-save cache)) + +(cl-defmethod pcache-purge-invalid ((cache pcache-repository)) + (let ((table (oref cache entries))) + (maphash (lambda (k e) + (unless (pcache-entry-valid-p e) + (remhash k table))) + table) + (pcache-save cache))) + +(cl-defmethod pcache-save ((cache pcache-repository) &optional force) + (let ((timestamp (oref cache timestamp)) + (delay (oref cache save-delay)) + (time (float-time (current-time)))) + (when (or force (> time (+ timestamp delay))) + (oset cache :timestamp time) + ;; make sure version is saved to file + (oset cache :version (oref-default (eieio-object-class cache) version-constant)) + (eieio-persistent-save cache)))) + +(cl-defmethod pcache-map ((cache pcache-repository) func) + (let ((table (oref cache entries))) + (maphash func table))) + +(defun pcache-kill-emacs-hook () + (maphash (lambda (k v) + (condition-case nil + (pcache-purge-invalid v) + (error nil)) + (condition-case nil + (pcache-save v t) + (error nil))) + *pcache-repositories*)) + +(defun pcache-destroy-repository (name) + (remhash name *pcache-repositories*) + (let ((fname (concat pcache-directory name))) + (when (file-exists-p fname) + (delete-file fname)))) + +(add-hook 'kill-emacs-hook #'pcache-kill-emacs-hook) + +;; in case we reload in place, clean all repositories with invalid version +(let (to-clean) + (maphash (lambda (k v) + (condition-case nil + (unless (eql (oref v version) + pcache-version-constant) + (signal 'error nil)) + (error + (setq to-clean (cons k to-clean))))) + *pcache-repositories*) + (dolist (k to-clean) + (remhash k *pcache-repositories*))) + +(provide 'pcache) +;;; pcache.el ends here