{-| This modules defines the data structure used to store the URLs in memory and on disk. -} module Breve.UrlTable ( UrlTable , load , save , 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 save a 'UrlTable' to a file sync :: UrlTable -> FilePath -> IO () sync table file = forever $ do threadDelay (round 3.0e8) save table file -- | Writes a 'UrlTable' to a file -- -- The table is stored in a text file -- as Haskell code for semplicity. save :: UrlTable -> FilePath -> IO () save table file = do content <- show <$> H.toList table writeFile file content putStrLn "\n[breve] url table synced." -- | Loads a URL table from a file -- -- Once the file is loaded it will be synced -- periodically (every 5min) on the disk. 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