home *** CD-ROM | disk | FTP | other *** search
-
- <HTML>
- <HEAD>
- <TITLE>Storable - persistency for perl data structures</TITLE>
- <LINK REL="stylesheet" HREF="../../Active.css" TYPE="text/css">
- <LINK REV="made" HREF="mailto:">
- </HEAD>
-
- <BODY>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> Storable - persistency for perl data structures</P></STRONG>
- </TD></TR>
- </TABLE>
-
- <A NAME="__index__"></A>
- <!-- INDEX BEGIN -->
-
- <UL>
-
- <LI><A HREF="#name">NAME</A></LI><LI><A HREF="#supportedplatforms">SUPPORTED PLATFORMS</A></LI>
-
- <LI><A HREF="#synopsis">SYNOPSIS</A></LI>
- <LI><A HREF="#description">DESCRIPTION</A></LI>
- <LI><A HREF="#memory store">MEMORY STORE</A></LI>
- <LI><A HREF="#speed">SPEED</A></LI>
- <LI><A HREF="#canonical representation">CANONICAL REPRESENTATION</A></LI>
- <LI><A HREF="#wizards only">WIZARDS ONLY</A></LI>
- <LI><A HREF="#examples">EXAMPLES</A></LI>
- <LI><A HREF="#warning">WARNING</A></LI>
- <LI><A HREF="#bugs">BUGS</A></LI>
- <LI><A HREF="#credits">CREDITS</A></LI>
- <LI><A HREF="#translations">TRANSLATIONS</A></LI>
- <LI><A HREF="#author">AUTHOR</A></LI>
- </UL>
- <!-- INDEX END -->
-
- <HR>
- <P>
- <H1><A NAME="name">NAME</A></H1>
- <P>Storable - persistency for perl data structures</P>
- <P>
- <HR>
- <H1><A NAME="supportedplatforms">SUPPORTED PLATFORMS</A></H1>
- <UL>
- <LI>Linux</LI>
- <LI>Solaris</LI>
- <LI>Windows</LI>
- </UL>
- <HR>
- <H1><A NAME="synopsis">SYNOPSIS</A></H1>
- <PRE>
- use Storable;
- store \%table, 'file';
- $hashref = retrieve('file');</PRE>
- <PRE>
- use Storable qw(nstore store_fd nstore_fd freeze thaw dclone);</PRE>
- <PRE>
- # Network order
- nstore \%table, 'file';
- $hashref = retrieve('file'); # There is NO nretrieve()</PRE>
- <PRE>
- # Storing to and retrieving from an already opened file
- store_fd \@array, \*STDOUT;
- nstore_fd \%table, \*STDOUT;
- $aryref = retrieve_fd(\*SOCKET);
- $hashref = retrieve_fd(\*SOCKET);</PRE>
- <PRE>
- # Serializing to memory
- $serialized = freeze \%table;
- %table_clone = %{ thaw($serialized) };</PRE>
- <PRE>
- # Deep (recursive) cloning
- $cloneref = dclone($ref);</PRE>
- <P>
- <HR>
- <H1><A NAME="description">DESCRIPTION</A></H1>
- <P>The Storable package brings persistency to your perl data structures
- containing SCALAR, ARRAY, HASH or REF objects, i.e. anything that can be
- convenientely stored to disk and retrieved at a later time.</P>
- <P>It can be used in the regular procedural way by calling <CODE>store</CODE> with
- a reference to the object to be stored, along with the file name where
- the image should be written.
- The routine returns <A HREF="../../lib/Pod/perlfunc.html#item_undef"><CODE>undef</CODE></A> for I/O problems or other internal error,
- a true value otherwise. Serious errors are propagated as a <A HREF="../../lib/Pod/perlfunc.html#item_die"><CODE>die</CODE></A> exception.</P>
- <P>To retrieve data stored to disk, use <CODE>retrieve</CODE> with a file name,
- and the objects stored into that file are recreated into memory for you,
- a <EM>reference</EM> to the root object being returned. In case an I/O error
- occurs while reading, <A HREF="../../lib/Pod/perlfunc.html#item_undef"><CODE>undef</CODE></A> is returned instead. Other serious
- errors are propagated via <A HREF="../../lib/Pod/perlfunc.html#item_die"><CODE>die</CODE></A>.</P>
- <P>Since storage is performed recursively, you might want to stuff references
- to objects that share a lot of common data into a single array or hash
- table, and then store that object. That way, when you retrieve back the
- whole thing, the objects will continue to share what they originally shared.</P>
- <P>At the cost of a slight header overhead, you may store to an already
- opened file descriptor using the <CODE>store_fd</CODE> routine, and retrieve
- from a file via <CODE>retrieve_fd</CODE>. Those names aren't imported by default,
- so you will have to do that explicitely if you need those routines.
- The file descriptor you supply must be already opened, for read
- if you're going to retrieve and for write if you wish to store.</P>
- <PRE>
- store_fd(\%table, *STDOUT) || die "can't store to stdout\n";
- $hashref = retrieve_fd(*STDIN);</PRE>
- <P>You can also store data in network order to allow easy sharing across
- multiple platforms, or when storing on a socket known to be remotely
- connected. The routines to call have an initial <CODE>n</CODE> prefix for <EM>network</EM>,
- as in <CODE>nstore</CODE> and <CODE>nstore_fd</CODE>. At retrieval time, your data will be
- correctly restored so you don't have to know whether you're restoring
- from native or network ordered data.</P>
- <P>When using <CODE>retrieve_fd</CODE>, objects are retrieved in sequence, one
- object (i.e. one recursive tree) per associated <CODE>store_fd</CODE>.</P>
- <P>If you're more from the object-oriented camp, you can inherit from
- Storable and directly store your objects by invoking <CODE>store</CODE> as
- a method. The fact that the root of the to-be-stored tree is a
- blessed reference (i.e. an object) is special-cased so that the
- retrieve does not provide a reference to that object but rather the
- blessed object reference itself. (Otherwise, you'd get a reference
- to that blessed object).</P>
- <P>
- <HR>
- <H1><A NAME="memory store">MEMORY STORE</A></H1>
- <P>The Storable engine can also store data into a Perl scalar instead, to
- later retrieve them. This is mainly used to freeze a complex structure in
- some safe compact memory place (where it can possibly be sent to another
- process via some IPC, since freezing the structure also serializes it in
- effect). Later on, and maybe somewhere else, you can thaw the Perl scalar
- out and recreate the original complex structure in memory.</P>
- <P>Surprisingly, the routines to be called are named <CODE>freeze</CODE> and <CODE>thaw</CODE>.
- If you wish to send out the frozen scalar to another machine, use
- <CODE>nfreeze</CODE> instead to get a portable image.</P>
- <P>Note that freezing an object structure and immediately thawing it
- actually achieves a deep cloning of that structure. Storable provides
- you with a <CODE>dclone</CODE> interface which does not create that intermediary
- scalar but instead freezes the structure in some internal memory space
- and then immediatly thaws it out.</P>
- <P>
- <HR>
- <H1><A NAME="speed">SPEED</A></H1>
- <P>The heart of Storable is written in C for decent speed. Extra low-level
- optimization have been made when manipulating perl internals, to
- sacrifice encapsulation for the benefit of a greater speed.</P>
- <P>Storage is now slightly slower than retrieval since the former has to
- also store data in a hash table to keep track of which objects
- have been stored already, whilst the latter uses an array instead of
- a hash table.</P>
- <P>On my HP 9000/712 machine running HPUX 9.03 and with perl 5.004, I can
- store 0.85 Mbyte/s and I can retrieve at 0.90 Mbytes/s, approximatively
- (CPU + system time).
- This was measured with Benchmark and the <EM>Magic: The Gathering</EM>
- database from Tom Christiansen (1.6 Mbytes on disk).</P>
- <P>
- <HR>
- <H1><A NAME="canonical representation">CANONICAL REPRESENTATION</A></H1>
- <P>Normally Storable stores elements of hashes in the order they are
- stored internally by Perl, i.e. pseudo-randomly. If you set
- <CODE>$Storable::canonical</CODE> to some <CODE>TRUE</CODE> value, Storable will store
- hashes with the elements sorted by their key. This allows you to
- compare data structures by comparing their frozen representations (or
- even the compressed frozen representations), which can be useful for
- creating lookup tables for complicated queries.</P>
- <P>Canonical order does not imply network order, those are two orthogonal
- settings.</P>
- <P>
- <HR>
- <H1><A NAME="wizards only">WIZARDS ONLY</A></H1>
- <P>The <CODE>Storable::last_op_in_netorder()</CODE> predicate will tell you whether
- network order was used in the last store or retrieve operation. If you
- don't know how to use this, just forget about it.</P>
- <P>
- <HR>
- <H1><A NAME="examples">EXAMPLES</A></H1>
- <P>Here are some code samples showing a possible usage of Storable:</P>
- <PRE>
- use Storable qw(store retrieve freeze thaw dclone);</PRE>
- <PRE>
- %color = ('Blue' => 0.1, 'Red' => 0.8, 'Black' => 0, 'White' => 1);</PRE>
- <PRE>
- store(\%color, '/tmp/colors') or die "Can't store %a in /tmp/colors!\n";</PRE>
- <PRE>
- $colref = retrieve('/tmp/colors');
- die "Unable to retrieve from /tmp/colors!\n" unless defined $colref;
- printf "Blue is still %lf\n", $colref->{'Blue'};</PRE>
- <PRE>
- $colref2 = dclone(\%color);</PRE>
- <PRE>
- $str = freeze(\%color);
- printf "Serialization of %%color is %d bytes long.\n", length($str);
- $colref3 = thaw($str);</PRE>
- <P>which prints (on my machine):</P>
- <PRE>
- Blue is still 0.100000
- Serialization of %color is 102 bytes long.</PRE>
- <P>
- <HR>
- <H1><A NAME="warning">WARNING</A></H1>
- <P>If you're using references as keys within your hash tables, you're bound
- to disapointment when retrieving your data. Indeed, Perl stringifies
- references used as hash table keys. If you later wish to access the
- items via another reference stringification (i.e. using the same
- reference that was used for the key originally to record the value into
- the hash table), it will work because both references stringify to the
- same string.</P>
- <P>It won't work across a <CODE>store</CODE> and <CODE>retrieve</CODE> operations however, because
- the addresses in the retrieved objects, which are part of the stringified
- references, will probably differ from the original addresses. The
- topology of your structure is preserved, but not hidden semantics
- like those.</P>
- <P>On platforms where it matters, be sure to call <A HREF="../../lib/Pod/perlfunc.html#item_binmode"><CODE>binmode()</CODE></A> on the
- descriptors that you pass to Storable functions.</P>
- <P>Storing data canonically that contains large hashes can be
- significantly slower than storing the same data normally, as
- temprorary arrays to hold the keys for each hash have to be allocated,
- populated, sorted and freed. Some tests have shown a halving of the
- speed of storing -- the exact penalty will depend on the complexity of
- your data. There is no slowdown on retrieval.</P>
- <P>
- <HR>
- <H1><A NAME="bugs">BUGS</A></H1>
- <P>You can't store GLOB, CODE, FORMLINE, etc... If you can define
- semantics for those operations, feel free to enhance Storable so that
- it can deal with them.</P>
- <P>The store functions will <CODE>croak</CODE> if they run into such references
- unless you set <CODE>$Storable::forgive_me</CODE> to some <CODE>TRUE</CODE> value. In that
- case, the fatal message is turned in a warning and some
- meaningless string is stored instead.</P>
- <P>Setting <CODE>$Storable::canonical</CODE> may not yield frozen strings that
- compare equal due to possible stringification of numbers. When the
- string version of a scalar exists, it is the form stored, therefore
- if you happen to use your numbers as strings between two freezing
- operations on the same data structures, you will get different
- results.</P>
- <P>Due to the aforementionned optimizations, Storable is at the mercy
- of perl's internal redesign or structure changes. If that bothers
- you, you can try convincing Larry that what is used in Storable
- should be documented and consistently kept in future revisions.</P>
- <P>
- <HR>
- <H1><A NAME="credits">CREDITS</A></H1>
- <P>Thank you to (in chronological order):</P>
- <PRE>
- Jarkko Hietaniemi <jhi@iki.fi>
- Ulrich Pfeifer <pfeifer@charly.informatik.uni-dortmund.de>
- Benjamin A. Holzman <benjamin.a.holzman@bender.com>
- Andrew Ford <A.Ford@ford-mason.co.uk>
- Gisle Aas <gisle@aas.no>
- Jeff Gresham <gresham_jeffrey@jpmorgan.com>
- Murray Nesbitt <murray@activestate.com></PRE>
- <P>for their bug reports, suggestions and contributions.</P>
- <P>Benjamin Holzman contributed the tied variable support, Andrew Ford
- contributed the canonical order for hashes, and Gisle Aas fixed
- a few misunderstandings of mine regarding the Perl internals,
- and optimized the emission of ``tags'' in the output streams by
- simply counting the objects instead of tagging them (leading to
- a binary incompatibility for the Storable image starting at version
- 0.6--older images are of course still properly understood).
- Murray Nesbitt made Storable thread-safe.</P>
- <P>
- <HR>
- <H1><A NAME="translations">TRANSLATIONS</A></H1>
- <P>There is a Japanese translation of this man page available at
- <A HREF="http://member.nifty.ne.jp/hippo2000/perltips/storable.htm">http://member.nifty.ne.jp/hippo2000/perltips/storable.htm</A> ,
- courtesy of Kawai, Takanori <<A HREF="mailto:kawai@nippon-rad.co.jp">kawai@nippon-rad.co.jp</A>>.</P>
- <P>
- <HR>
- <H1><A NAME="author">AUTHOR</A></H1>
- <P>Raphael Manfredi <EM><<A HREF="mailto:Raphael_Manfredi@pobox.com">Raphael_Manfredi@pobox.com</A>></EM></P>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> Storable - persistency for perl data structures</P></STRONG>
- </TD></TR>
- </TABLE>
-
- </BODY>
-
- </HTML>
-