The Awesome Factor

Serialization To Disk

Saturday, December 30, 2006

#furnace #wee-url.com

For fun, I wrote a TinyURL clone in Factor. You can try it out at http://wee-url.com. I needed a way to save the data to a file, so I used libs/serialize to serialize the hashtable containing the links. There was yet another bug involving vector literals – the serialization code would reuse a vector, so the first time you serialized the output is correct, but the next time it would produce garbage.

IN: scratchpad SYMBOL: aa H{ { 1 2 } } aa set

IN: scratchpad aa get .
H{ { 1 2 } }

IN: scratchpad aa get [ [ serialize ] with-serialized ] string-out .
"hp\0\0\0\u0001Dap\0\0\0\u0001Ep\0\0\0\u0001\u0001ap\0\0..."

IN: scratchpad aa get [ [ serialize ] with-serialized ] string-out .
"op\0\0\0\u0001:"

The fix was to change a V{ } to a V{ } clone.

Serialization to Disk Code

: save-fstore ( variable path -- )
     [ [ get serialize ] with-serialized ] with-stream ;

: load-fstore ( variable path -- )
    dup exists? [
         [ [ deserialize ] with-serialized ] with-stream
        swap
    ] [
        drop >r H{ } clone r>
    ] if set-global ;

: fstore-set ( variable fstore -- )
    get >r [ get ] keep r> set-hash ;

: fstore-get ( default variable fstore -- )
    get dupd hash* [ swap set-global drop ] [ drop set-global ] if ;

save-fstore and load-fstore save/load a hashtable to disk. The hashtable keys are variable names and the values are the variable values. fstore-set puts your variable in the hashtable, so you should call this directly before saving to disk. fstore-get loads the data from your store. If there is no fstore or if the key does not exist, it uses your default value.

The loading code is pretty simple:

: fstore-name "wee-url.fstore" ;
SYMBOL: wee-shortcuts
SYMBOL: wee-fstore
wee-fstore fstore-name load-fstore
H{ } clone wee-shortcuts wee-fstore fstore-get

The variable wee-shortcuts stores the encoded URLs, while wee-fstore is the hashtable that the above code reads/writes to disk.

Finally, to write the store:

: save-shortcuts ( -- )
    wee-shortcuts wee-fstore fstore-set
    wee-fstore fstore-name save-fstore ;

Notice that we add wee-shortcuts to the hashtable before saving to disk.

I’m going to rewrite the wee-url code to use Furnace instead of callback-responder. Once I get it looking nice, I’ll show you how it works.