content: module Network.Neks.Disk (saveTo, loadFrom) where
  
  import Control.Concurrent.STM (atomically)
  import Network.Neks.DataStore (DataStore, dump, load)
  import Network.Neks.NetPack (netRead, netWrite) -- also works on files
  import System.IO (Handle, withFile, IOMode(ReadMode, WriteMode))
  import System.Directory (renameFile, doesFileExist)
  import Data.Serialize (Serialize, encode, decode)
  import Control.Applicative ((<$>))
  
  saveTo :: (Serialize a, Ord a, Serialize b) => String -> DataStore a b -> IO ()
  saveTo path store = do
          withFile (path ++ "~") WriteMode (`saveToHandle` store)
          renameFile (path ++ "~") path
  saveToHandle handle store = do
          maps <- atomically (dump store)
          sequence_ [netWrite handle (encode map) | map <- maps]
  
  loadFrom :: (Serialize a, Ord a, Serialize b) => String -> IO (Maybe (DataStore a b))
  loadFrom path = doesFileExist path >>= \exists -> if exists
          then Just <$> withFile path ReadMode loadFromHandle
          else return Nothing
  loadFromHandle handle = do
          maps <- sequence . replicate 4096 $ do
                  mapData <- netRead handle
                  let Right map = mapData >>= decode
                  return map
          atomically (load maps)