53 lines
1.3 KiB
Haskell
53 lines
1.3 KiB
Haskell
{-|
|
|
This modules defines the data structure used
|
|
to store the URLs in memory and on disk.
|
|
-}
|
|
module Breve.UrlTable
|
|
( UrlTable
|
|
, load
|
|
, insert
|
|
, extract
|
|
) where
|
|
|
|
import Breve.Generator
|
|
|
|
import Control.Monad (forever)
|
|
import Control.Concurrent (forkIO, threadDelay)
|
|
import Text.Read (readMaybe)
|
|
import qualified Data.HashTable.IO as H
|
|
|
|
-- | The hash table that stores URLs
|
|
type UrlTable = H.CuckooHashTable Name Url
|
|
|
|
-- | Periodically writes a 'UrlTable' to a file
|
|
--
|
|
-- The table is stored in a text file
|
|
-- as Haskell code for semplicity.
|
|
sync :: UrlTable -> FilePath -> IO ()
|
|
sync table file = forever $ do
|
|
threadDelay (round 3.0e8)
|
|
content <- show <$> H.toList table
|
|
writeFile file content
|
|
|
|
-- | Loads a URL table from a file
|
|
--
|
|
-- The format should be the same one used
|
|
-- by the 'sync' function.
|
|
load :: FilePath -> IO UrlTable
|
|
load file = do
|
|
content <- readFile file
|
|
table <- case readMaybe content of
|
|
Just list -> H.fromList list
|
|
Nothing -> H.new
|
|
forkIO (sync table file)
|
|
return table
|
|
|
|
-- | Insert the URL in a table and return the name
|
|
insert :: UrlTable -> Url -> IO Name
|
|
insert table url = H.insert table new url >> return new
|
|
where new = nameHash url
|
|
|
|
-- | Lookup a table for the associated URL
|
|
extract :: UrlTable -> Name -> IO (Maybe Url)
|
|
extract = H.lookup
|