[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: circular structures and bin files
1. I would like to add my vote for better .bin file prototcol for
flavors. (It has always seemed unsymbolics like that the dumper can
recognize circularity but can't handle it.) If :FASD-FORM created the
instance and then initialized it a lot of common things like flavors
having back pointers to other flavors would just dump like arrays do.
Circular lists would still be a problem but i agree that they don't
occur that often in practice. Perhaps there could be a flag to let
you pay the price when you want to.
2. It would also be nice if you could control the size of the
dumper's hash table. When i've dumped big arrays of things, i've
noticed that a lot of time is spent simply growing the table larger
and larger. With the GC getting involved, because of all the consing
to produce the fasd froms, dumping becomes very slow.
Here is some code that i use for dumping instances with circular
references. Basically it dumps an instance followed by any circular
references.
;;; DUMPABLE MIXIN
(defvar *after-fasd-forms* nil
"Forms to dump after instances are made.")
;;; This is a version of DUMP-FORMS-TO-FILE that lets you send messages to
;;; instance after you create them, so you can avoid circular references.
(DEFUN DUMP-delayed-FORMS-TO-FILE (FILENAME FORMS &OPTIONAL FILE-ATTRIBUTE-LIST)
;; If no package is specified for the file, use the USER package.
(let ((*after-fasd-forms* nil))
(UNLESS (GET (LOCF FILE-ATTRIBUTE-LIST) ':PACKAGE)
(PUTPROP (LOCF FILE-ATTRIBUTE-LIST) ':USER ':PACKAGE))
(si:WRITING-BIN-FILE
(STREAM FILENAME)
(si:DUMP-ATTRIBUTE-LIST FILE-ATTRIBUTE-LIST STREAM)
(DOLIST (FORM FORMS)
(si:DUMP-FORM-TO-EVAL FORM STREAM)
(loop while *after-fasd-forms*
do (si:dump-form-to-eval (pop *after-fasd-forms*) stream))))))
(defflavor dumpable-mixin
()
()
(:method-combination :fasd-items (:append :most-specific-first)
:after-fasd-forms (:append :most-specific-first))
(:documentation
"A mixin for dumping flavors to binary files.
Each flavor built on this can provide a :FASD-ITEMS method that returns
a list of keyword value pairs used to dump the object.
An :AFTER-FASD-FORMS method can be used to create possibly circular structure."))
(defmethod (:fasd-form dumpable-mixin) ()
"Returns a form used to dump SELF to a file.
You may want to redefine this method."
(setq *after-fasd-forms* ; Save things to do after self
; is loaded.
(nconc (send self :after-fasd-forms) *after-fasd-forms*))
(send self :fasd-instance-form))
(defmethod (:fasd-instance-form dumpable-mixin) ()
1;; Form to create the instance.
2 `(make-instance ',(typep self) ,@(send self :fasd-items)))
(defmethod (:fasd-items dumpable-mixin) () ()) ; Stub.
(defmethod (:after-fasd-forms dumpable-mixin) () ()) ; Stub.