[rucksack-cvs] CVS rucksack
alemmens
alemmens at common-lisp.net
Mon Jan 22 10:23:14 UTC 2007
Update of /project/rucksack/cvsroot/rucksack
In directory clnet:/tmp/cvs-serv24110
Modified Files:
do.txt done.txt rucksack.asd serialize.lisp
Log Message:
Version 0.1.6 - Added serializing/deserializing of structures. Only
works on SBCL. (Thanks to Levente Mészáros.)
--- /project/rucksack/cvsroot/rucksack/do.txt 2006/09/04 12:34:34 1.5
+++ /project/rucksack/cvsroot/rucksack/do.txt 2007/01/22 10:23:14 1.6
@@ -1,14 +1,10 @@
DO:
-- In SBCL, FINALIZE-INHERITANCE is not called when a class was redefined
- and a new instance of the redefined class is created. (In Lispworks,
- it *is* called then.)
-
-- Make Rucksack crash proof. (Use a copying GC?)
-
- There's still a btree bug that's detected (very rarely) by the
stress test. Fix it.
+- Make Rucksack crash proof. (Use a copying GC?)
+
- Check that btrees actually signal an error for duplicate keys.
Handle those errors correctly for slot indexes.
--- /project/rucksack/cvsroot/rucksack/done.txt 2006/11/30 10:45:34 1.6
+++ /project/rucksack/cvsroot/rucksack/done.txt 2007/01/22 10:23:14 1.7
@@ -1,3 +1,9 @@
+* 2007-01-21 - version 0.1.6
+
+- Added serializing/deserializing of structures. Only works on SBCL.
+ (Thanks to Levente Mészáros.)
+
+
* 2006-11-30
- FLET MAP-INDEXES should be LABELS MAP-INDEXES (thanks to Cyrus Harmon)
--- /project/rucksack/cvsroot/rucksack/rucksack.asd 2007/01/20 18:17:55 1.7
+++ /project/rucksack/cvsroot/rucksack/rucksack.asd 2007/01/22 10:23:14 1.8
@@ -1,9 +1,9 @@
-;;; $Id: rucksack.asd,v 1.7 2007/01/20 18:17:55 alemmens Exp $
+;;; $Id: rucksack.asd,v 1.8 2007/01/22 10:23:14 alemmens Exp $
(in-package :cl-user)
(asdf:defsystem :rucksack
- :version "0.1.5"
+ :version "0.1.6"
:serial t
:components ((:file "queue")
(:file "package")
--- /project/rucksack/cvsroot/rucksack/serialize.lisp 2007/01/20 18:17:55 1.9
+++ /project/rucksack/cvsroot/rucksack/serialize.lisp 2007/01/22 10:23:14 1.10
@@ -1,4 +1,4 @@
-;; $Id: serialize.lisp,v 1.9 2007/01/20 18:17:55 alemmens Exp $
+;; $Id: serialize.lisp,v 1.10 2007/01/22 10:23:14 alemmens Exp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Serialize
@@ -170,6 +170,7 @@
(defconstant +unbound-slot+ #x71)
(defconstant +shared-object-definition+ #x72)
(defconstant +shared-object-reference+ #x73)
+(defconstant +structure-object+ #x77)
;; Rest
@@ -1133,9 +1134,57 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Structures
;;;
-;;; Can't be serialized portably. Let's forget about them here.
+;;; Can't be serialized portably. The version below works for SBCL at the
+;;; moment, but using structures in Rucksack is risky: if a structure
+;;; definition changes, Rucksack won't know about it and you'll probably
+;;; run into big problems.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+#+sbcl
+(defmethod serialize ((object structure-object) serializer)
+ (serialize-structure-object object serializer))
+
+(defun serialize-structure-object (object serializer)
+ ;; A structure object is serialized as:
+ ;; - structure name
+ ;; - number of slots
+ ;; - slot values
+ (serialize-marker +structure-object+ serializer)
+ (serialize (class-name (class-of object)) serializer)
+ (save-slots object serializer))
+
+(defmethod save-slots ((object structure-object) serializer)
+ (let ((slots (saved-slots object)))
+ (serialize (length slots) serializer)
+ (loop for slot-name in (saved-slots object)
+ do (serialize (slot-value object slot-name) serializer))))
+
+#+sbcl
+(defmethod deserialize-contents ((marker (eql +structure-object+)) serializer)
+ (let* ((class-name (deserialize serializer))
+ (object (allocate-instance (find-class class-name))))
+ (load-slots object serializer)))
+
+(defmethod load-slots ((object structure-object) stream)
+ (let ((nr-slots (deserialize stream))
+ (slots (saved-slots object)))
+ (unless (= nr-slots (length slots))
+ (error "Slot mismatch while deserializing a structure object of class ~S."
+ (class-of object)))
+ (loop for slot-name in (saved-slots object)
+ do (let ((marker (read-next-marker stream)))
+ (setf (slot-value object slot-name)
+ (deserialize-contents marker stream))))
+ object))
+
+(defmethod scan-contents ((marker (eql +structure-object+)) serializer gc)
+ ;; Skip class name
+ (scan serializer gc)
+ ;; Scan all slots
+ (let ((nr-slots (deserialize serializer)))
+ (loop repeat nr-slots
+ do (scan serializer gc))))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Arrays
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
More information about the rucksack-cvs
mailing list