[rucksack-cvs] CVS rucksack

alemmens alemmens at common-lisp.net
Fri Aug 4 10:26:24 UTC 2006


Update of /project/rucksack/cvsroot/rucksack
In directory clnet:/tmp/cvs-serv23361

Modified Files:
	heap.lisp serialize.lisp 
Log Message:
Add missing SCAN-CONTENTS methods for efficiency (from Edi Weitz).


--- /project/rucksack/cvsroot/rucksack/heap.lisp	2006/08/03 11:39:39	1.8
+++ /project/rucksack/cvsroot/rucksack/heap.lisp	2006/08/04 10:26:23	1.9
@@ -1,4 +1,4 @@
-;; $Id: heap.lisp,v 1.8 2006/08/03 11:39:39 alemmens Exp $
+;; $Id: heap.lisp,v 1.9 2006/08/04 10:26:23 alemmens Exp $
 
 (in-package :rucksack)
 
@@ -493,6 +493,9 @@
            (error "Unexpected end of serialization buffer at ~D."
                   scan-pointer)))))
 
+(defmethod scan-byte ((stream serialization-buffer) &optional gc)
+  (declare (ignore gc))
+  (deserialize-byte stream t))
 
 ;;
 ;; Loading/saving buffers
--- /project/rucksack/cvsroot/rucksack/serialize.lisp	2006/08/03 10:59:52	1.4
+++ /project/rucksack/cvsroot/rucksack/serialize.lisp	2006/08/04 10:26:23	1.5
@@ -1,4 +1,4 @@
-;; $Id: serialize.lisp,v 1.4 2006/08/03 10:59:52 alemmens Exp $
+;; $Id: serialize.lisp,v 1.5 2006/08/04 10:26:23 alemmens Exp $
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Serialize
@@ -210,6 +210,14 @@
   (:method ((stream stream) &optional (eof-error-p t))
    (read-byte stream eof-error-p nil)))
 
+(defgeneric scan-byte (serializer &optional gc)
+  (:documentation "Skips an unsigned byte from the serializer.")
+  (:method ((serializer serializer) &optional gc)
+   (declare (ignore gc))
+   (read-byte (serializer-stream serializer) t nil))
+  (:method ((stream stream) &optional gc)
+   (declare (ignore gc))
+   (read-byte stream t nil)))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; SERIALIZE/DESERIALIZE/SCAN
@@ -223,9 +231,6 @@
 
 (defmethod scan-contents (marker serializer gc)
   ;; Default: just deserialize the contents but don't evacuate anything.
-  ;; EFFICIENCY: This is rather inefficient because it will reconstruct objects
-  ;; that don't really need to be reconstructed.  Improve this by writing
-  ;; special methods for those objects (numbers, strings, etc.)
   (declare (ignore gc))
   (deserialize-contents marker serializer))
 
@@ -321,6 +326,10 @@
 ;;; Integers
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+;;
+;; Serializing multiple bytes
+;;
+
 (defun serialize-byte-16 (integer stream)
   (serialize-byte (ldb (byte 8 0) integer) stream)
   (serialize-byte (ldb (byte 8 8) integer) stream))
@@ -349,6 +358,10 @@
     (serialize-byte-32 most-significant stream)))
 
 
+;;
+;; Deserializing multiple bytes
+;;
+
 (defun deserialize-byte-16 (stream)
   (+ (deserialize-byte stream)
      (* (deserialize-byte stream) 256)))
@@ -372,6 +385,39 @@
   (+ (deserialize-byte-32 stream)
      (* (deserialize-byte-32 stream) #x100000000)))
 
+;;
+;; Scanning multiple bytes
+;;
+
+(defun scan-byte-16 (stream &optional gc)
+  (declare (ignore gc))
+  (scan-byte stream)
+  (scan-byte stream))
+
+(defun scan-byte-24 (stream &optional gc)
+  (declare (ignore gc))
+  (dotimes (i 3)
+    (scan-byte stream)))
+
+(defun scan-byte-32 (stream &optional gc)
+  (declare (ignore gc))
+  (scan-byte-16 stream)
+  (scan-byte-16 stream))
+
+(defun scan-byte-48 (stream &optional gc)
+  (declare (ignore gc))
+  (scan-byte-24 stream)
+  (scan-byte-24 stream))
+
+(defun scan-byte-64 (stream &optional gc)
+  (declare (ignore gc))
+  (scan-byte-32 stream)
+  (scan-byte-32 stream))
+
+
+;;
+;; Serializing integers
+;;
 
 (defmethod serialize ((obj integer) stream)
   ;; Serialize integers with least-significant bytes first.
@@ -414,6 +460,74 @@
        (loop for position from (- nr-bits 8) downto 0 by 8
              do (serialize-byte (ldb (byte 8 position) unsigned) stream))))))
 
+
+;;
+;; Scanning integers
+;;
+
+(defmethod scan-contents ((marker (eql +positive-byte-8+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte stream))
+
+(defmethod scan-contents ((marker (eql +negative-byte-8+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte stream))
+
+(defmethod scan-contents ((marker (eql +positive-byte-16+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-16 stream))
+
+(defmethod scan-contents ((marker (eql +negative-byte-16+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-16 stream))
+
+(defmethod scan-contents ((marker (eql +positive-byte-24+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-24 stream))
+
+(defmethod scan-contents ((marker (eql +negative-byte-24+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-24 stream))
+
+(defmethod scan-contents ((marker (eql +positive-byte-32+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-32 stream))
+
+(defmethod scan-contents ((marker (eql +negative-byte-32+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-32 stream))
+
+(defmethod scan-contents ((marker (eql +positive-byte-48+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-48 stream))
+
+(defmethod scan-contents ((marker (eql +negative-byte-48+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-48 stream))
+
+(defmethod scan-contents ((marker (eql +positive-byte-64+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-64 stream))
+
+(defmethod scan-contents ((marker (eql +negative-byte-64+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-64 stream))
+
+(defmethod scan-contents ((marker (eql +positive-integer+)) stream gc)
+  (declare (ignore gc))
+  (let ((nr-bytes (deserialize stream)))
+    (assert (integerp nr-bytes))
+    (dotimes (i nr-bytes)
+      (scan-byte stream))))
+
+(defmethod scan-contents ((marker (eql +negative-integer+)) stream gc)
+  (scan-contents +positive-integer+ stream gc))
+
+
+;;
+;; Deserializing integers
+;;
+
 (defun nr-octets (n)
   (ceiling (integer-length n) 8))
 
@@ -493,6 +607,10 @@
 (defmethod deserialize-contents ((marker (eql +rational+)) stream)
   (/ (deserialize stream) (deserialize stream)))
 
+(defmethod scan-contents ((marker (eql +rational+)) stream gc)
+  (scan stream gc)
+  (scan stream gc))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Floats
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -516,6 +634,11 @@
          (sign (deserialize stream)))
     (* sign (scale-float (float significand 1.0L0) exponent))))
 
+(defmethod scan-contents ((marker (eql +float+)) stream gc)
+  ;; significand, exponent, sign
+  (dotimes (i 3)
+    (scan stream gc)))
+
 
 #|
 For more efficient ways of serializing floats, we may want to use
@@ -565,6 +688,10 @@
 (defmethod deserialize-contents ((marker (eql +complex+)) stream)
   (complex (deserialize stream) (deserialize stream)))
 
+(defmethod scan-contents ((marker (eql +complex+)) stream gc)
+  (scan stream gc)
+  (scan stream gc))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Conses
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -658,6 +785,10 @@
 ;;; Strings and characters
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+;;
+;; Serializing characters
+;;
+
 (defmethod serialize ((char character) stream)
   (unless (= (char-code char) (char-int char))
     (cerror "Serialize it anyway (without the attributes)."
@@ -680,6 +811,10 @@
           (t (serialize-marker +character+ stream)
              (serialize (char-code char) stream)))))
 
+;;
+;; Deserializing characters
+;;
+
 (defmethod deserialize-contents ((marker (eql +character+)) stream)
   (code-char (deserialize stream)))
 
@@ -695,6 +830,33 @@
 (defmethod deserialize-contents ((marker (eql +character-32+)) stream)
   (code-char (deserialize-byte-32 stream)))
 
+;;
+;; Scanning characters
+;;
+
+(defmethod scan-contents ((marker (eql +character+)) stream gc)
+  (scan stream gc))
+
+(defmethod scan-contents ((marker (eql +character-8+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte stream))
+
+(defmethod scan-contents ((marker (eql +character-16+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-16 stream))
+
+(defmethod scan-contents ((marker (eql +character-24+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-24 stream))
+
+(defmethod scan-contents ((marker (eql +character-32+)) stream gc)
+  (declare (ignore gc))
+  (scan-byte-32 stream))
+
+
+;;
+;; Serializing strings
+;;
 
 (defun max-character-code (string)
   "Returns the highest character code in string."
@@ -750,6 +912,54 @@
             do (funcall writer code stream)))))
 
 
+;;
+;; Scanning strings
+;;
+
+(defmethod scan-contents ((marker (eql +simple-string+)) stream gc)
+  (scan-string t #'scan stream gc))
+
+(defmethod scan-contents ((marker (eql +simple-string-8+)) stream gc)
+  (scan-string t #'scan-byte stream gc))
+
+(defmethod scan-contents ((marker (eql +simple-string-16+)) stream gc)
+  (scan-string t #'scan-byte-16 stream gc))
+
+(defmethod scan-contents ((marker (eql +simple-string-24+)) stream gc)
+  (scan-string t #'scan-byte-24 stream gc))
+
+(defmethod scan-contents ((marker (eql +simple-string-32+)) stream gc)
+  (scan-string t #'scan-byte-32 stream gc))
+
+(defmethod scan-contents ((marker (eql +string+)) stream gc)
+  (scan-string nil #'scan stream gc))
+
+(defmethod scan-contents ((marker (eql +string-8+)) stream gc)
+  (scan-string nil #'scan-byte stream gc))
+
+(defmethod scan-contents ((marker (eql +string-16+)) stream gc)
+  (scan-string nil #'scan-byte-16 stream gc))
+
+(defmethod scan-contents ((marker (eql +string-24+)) stream gc)
+  (scan-string nil #'scan-byte-24 stream gc))
+
+(defmethod scan-contents ((marker (eql +string-32+)) stream gc)
+  (scan-string nil #'scan-byte-32 stream gc))
+
+(defun scan-string (simple-p character-code-scanner stream gc)
+  (scan-byte stream) ; skip type marker
+  (unless simple-p
+    ;; fill pointer and adjustable-p
+    (scan stream gc)
+    (scan stream gc))
+  (loop repeat (deserialize stream) ; length
+        do (funcall character-code-scanner stream gc)))
+
+
+;;
+;; Deserializing strings
+;;
+
 (defmethod deserialize-contents ((marker (eql +simple-string+)) stream)
   (deserialize-string t #'deserialize stream))
 
@@ -831,9 +1041,19 @@
 (defmethod deserialize-contents ((marker (eql +keyword+)) stream)
   (intern (deserialize stream) (find-package :keyword)))
 
+(defmethod scan-contents ((marker (eql +keyword+)) stream gc)
+  ;; just the symbol name
+  (scan stream gc))
+
+
 (defmethod deserialize-contents ((marker (eql +uninterned-symbol+)) stream)
   (make-symbol (deserialize stream)))
 
+(defmethod scan-contents ((marker (eql +uninterned-symbol+)) stream gc)
+  ;; just the symbol name
+  (scan stream gc))
+
+
 (defmethod deserialize-contents ((marker (eql +symbol+)) stream)
   ;; Q: Maybe we should always create the package if it doesn't exist
   ;; (without even asking?)
@@ -847,6 +1067,11 @@
                        (make-package package-name))))
       (intern symbol-name package))))
 
+(defmethod scan-contents ((marker (eql +symbol+)) stream gc)
+  ;; package name, then symbol name
+  (scan stream gc)
+  (scan stream gc))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Objects
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -999,6 +1224,10 @@
                    :type type
                    :version version)))
 
+(defmethod scan-contents ((marker (eql +pathname+)) stream gc)
+  ;; skip host, device, directory, name, type, version
+  (dotimes (i 6)
+    (scan stream gc)))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Hash tables




More information about the rucksack-cvs mailing list