Mercurial > core / lisp/lib/obj/meta/storable.lisp
changeset 698: |
96958d3eb5b0 |
parent: |
9eb2c112aa16
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 ;;; obj/meta/storable.lisp --- Storable Objects 3 ;; The storable-class can be assigned to the :metaclass option of a 4 ;; class to allow persistent storage of an object on disk. The 5 ;; storable-slot-mixin is a custom slot option which can be used to 6 ;; selectively enable slot serialization. 10 ;; This code is derived from XDB. 12 ;; Note that this is not a general purpose SerDe. It is specifically designed 13 ;; to decode/encode objects as single octet-vectors from/to an open stream 14 ;; with minimal overhead. There is a separate interface for general-purpose 15 ;; data encoding which can be found in the DAT system. 18 (in-package :obj/meta/storable) 20 (sb-ext:unlock-package :sb-pcl) 23 (defclass storable-class (standard-class) 24 ((class-id :initform nil 26 (slots-to-store :initform nil :accessor slots-to-store) 27 (slot-locations-and-initforms 29 :accessor slot-locations-and-initforms) 30 (all-slot-locations-and-initforms 32 :accessor all-slot-locations-and-initforms) 33 (initforms :initform #() 34 :accessor class-initforms) 35 (id-cache :initarg :id-cache 36 :initform (make-hash-table :size 1000) 41 (defun initialize-storable-class (next-method class &rest args 42 &key direct-superclasses &allow-other-keys) 43 (apply next-method class 44 (if direct-superclasses 46 (list* :direct-superclasses (list (find-class 'storable-class)) 49 (defmethod initialize-instance :around ((class storable-class) 51 (apply #'initialize-storable-class #'call-next-method class args)) 53 (defmethod reinitialize-instance :around ((class storable-class) 55 (apply #'initialize-storable-class #'call-next-method class args)) 58 (defmethod validate-superclass 59 ((class standard-class) 60 (superclass storable-class)) 63 (defmethod validate-superclass 64 ((class storable-class) 65 (superclass standard-class)) 69 (defclass storable-slot-mixin () 70 ((storep :initarg :storep 72 :accessor store-slot-p))) 74 (defclass storable-direct-slot-definition (storable-slot-mixin 75 standard-direct-slot-definition) 78 (defclass storable-effective-slot-definition 79 (storable-slot-mixin standard-effective-slot-definition) 82 (defmethod direct-slot-definition-class ((class storable-class) 84 (declare (ignore initargs)) 85 (find-class 'storable-direct-slot-definition)) 87 (defmethod effective-slot-definition-class ((class storable-class) 88 &key &allow-other-keys) 89 (find-class 'storable-effective-slot-definition)) 91 (defmethod compute-effective-slot-definition 92 ((class storable-class) slot-name direct-definitions) 93 (declare (ignore slot-name)) 94 (let ((effective-definition (call-next-method)) 95 (direct-definition (car direct-definitions))) 96 (setf (store-slot-p effective-definition) 97 (store-slot-p direct-definition)) 98 effective-definition)) 100 (defun make-slots-cache (slot-definitions) 102 (lambda (slot-definition) 103 (cons (sb-mop:slot-definition-location slot-definition) 104 (sb-mop:slot-definition-initform slot-definition))) 107 (defun initialize-class-slots (class slots) 108 (let* ((slots-to-store (coerce (remove-if-not #'store-slot-p slots) 110 (setf (slots-to-store class) 112 (setf (slot-locations-and-initforms class) 113 (make-slots-cache slots-to-store)) 114 (setf (all-slot-locations-and-initforms class) 115 (make-slots-cache slots)) 116 (setf (class-initforms class) 117 (map 'vector #'sb-mop:slot-definition-initform slots)))) 119 (defmethod compute-slots :around ((class storable-class)) 120 (let ((slots (call-next-method))) 121 (initialize-class-slots class slots) 125 (sb-ext:lock-package :sb-pcl)