[comp.lang.lisp] Hash-table saving

pberck@kub.nl (Peter Berck) (05/03/91)

How can a save a hash-table to disk? I tried the obvious
(print *hash-table* my-stream) but this didn't work. It would just
save "#<hash-table 0017de20>" to disk. (It contains about 10000
entries).

Should I use something like (maphash ...) and save all key-value pairs
to disk? That will probably cost more time than generating it.

thanx,
-peter

------------------------------------------------------------------------
pberck@kub.nl                                             kubvx1::berckp
                         Back to Lisp Top Level

pab@lucid.com (Peter Benson) (05/03/91)

There is a hack that works (I think) in lucid common lisp. 
That is make a file with just

(in-package :whatever)
(setq *hash-table* '#.*hash-table*)

and then compile that file.  
I don't know if this is required to work by CLtL.  Any x3j13 people know if
this is clarified.

The other alternative is to generate a source file like:

(let ((hash-table (make-hash-table)))
  (dolist (pair
          '#.(let ((list nil))
              (maphash #'(lambda (k v)
                           (push (cons k v) list))
                       *hash-table*)
              list))
    (setf (gethash (car pair) hash-table) (cdr pair)))
  (setq *hash-table* hash-table))

and compile that file.
This will work as long as the keys and values in the hash table are things
that can be put in a compiled file.  Depending on how fast the binary file
loader is it may be faster than just putting the values in a file.  The
other advantage is that you don't have to worry about whether all the
objects in the hash table print readably.  

-ptr-
pab@lucid.com

moore%defmacro.utah.edu@cs.utah.edu (Tim Moore) (05/04/91)

In article <PAB.91May3123317@challenger.lucid.com> pab@lucid.com (Peter Benson) writes:
>There is a hack that works (I think) in lucid common lisp. 
>That is make a file with just
>
>(in-package :whatever)
>(setq *hash-table* '#.*hash-table*)
>
>and then compile that file.  
>I don't know if this is required to work by CLtL.  Any x3j13 people know if
>this is clarified.

One problem is that compiled constants are immutable, which means you
couldn't (portably) add or delete any entries in the hash table when
you loaded the file back in.

-- 
Tim Moore                    moore@cs.utah.edu {bellcore,hplabs}!utah-cs!moore
"Ah, youth. Ah, statute of limitations."
		-John Waters

mdb@zero.arc.ab.ca (Mark Brinsmead) (05/06/91)

In article <1991May3.134834.26515@hellgate.utah.edu>,
moore%defmacro.utah.edu@cs.utah.edu (Tim Moore) writes:
|> In article <PAB.91May3123317@challenger.lucid.com> pab@lucid.com
(Peter Benson) writes:
|> >There is a hack that works (I think) in lucid common lisp. 
|> >That is make a file with just
|> >
|> >(in-package :whatever)
|> >(setq *hash-table* '#.*hash-table*)
|> >
|> >and then compile that file.  
|> >I don't know if this is required to work by CLtL.  Any x3j13 people know if
|> >this is clarified.
|> 
|> One problem is that compiled constants are immutable, which means you
|> couldn't (portably) add or delete any entries in the hash table when
|> you loaded the file back in.
|> 

    There are *portable* ways to get around this.  I have already
"advertised" a
CLOS-based package for saving common-lisp and CLOS objects by producing
(sometimes
large) source files which will re-create them.  It is possible to
preserve eq-ness
throughout arbitrary structures, and to save (and restore) structures with
arbitrary circularity.

    The package will save objects of almost any type (I still haven't figured
out how to do defstruct's portably) including hash-tables, and CLOS instances.
Its biggest problem is an occasional tendency to save *more* than you want it
to!

    Unfortunately, I am still awaiting clearance to release the source code.
When (if) I get it, the code will be released on comp.lang.clos.


-- Mark Brinsmead
   Alberta Research Council
   Calgary Alberta Canada.

   email:     mdb@arcsun.arc.ab.ca
   telephone: (403) 297-2600

jpalmucc@bbn.com (Jeff Palmucci) (05/09/91)

pberck@kub.nl (Peter Berck) writes:

>How can a save a hash-table to disk? I tried the obvious
>(print *hash-table* my-stream) but this didn't work. It would just
>save "#<hash-table 0017de20>" to disk. (It contains about 10000
>entries).

In Lucid, you can (princ "(Setq *hash-table* #.*hash-table*)"
my-stream) and then (compile-file my-file). The binary version will
have an image of the hash table. With symbolics, use sys:dump-forms-to-file.

Jeff