on master help sign in
Merge branch 'stable'
484e0fbJasper Van der Jeugt
src/Hakyll/Core/Configuration.hs+4
@@ -40,6 +40,9 @@ data HakyllConfiguration = HakyllConfiguration
40 -- > ./hakyll deploy
40 -- > ./hakyll deploy
41 --
41 --
42 deployCommand :: String
42 deployCommand :: String
43+ , -- | Use an in-memory cache for items. This is faster but uses more
44+ -- memory.
45+ inMemoryCache :: Bool
43 }
46 }
44
47
45-- | Default configuration for a hakyll application
48-- | Default configuration for a hakyll application
@@ -50,6 +53,7 @@ defaultHakyllConfiguration = HakyllConfiguration
50 , storeDirectory = "_cache"
53 , storeDirectory = "_cache"
51 , ignoreFile = ignoreFile'
54 , ignoreFile = ignoreFile'
52 , deployCommand = "echo 'No deploy command specified'"
55 , deployCommand = "echo 'No deploy command specified'"
56+ , inMemoryCache = False
53 }
57 }
54 where
58 where
55 ignoreFile' path
59 ignoreFile' path
src/Hakyll/Core/Run.hs+1−1
@@ -42,7 +42,7 @@ run configuration rules = do
42
42
43 section logger "Initialising"
43 section logger "Initialising"
44 store <- timed logger "Creating store" $
44 store <- timed logger "Creating store" $
45− makeStore $ storeDirectory configuration
45+ makeStore (inMemoryCache configuration) $ storeDirectory configuration
46 provider <- timed logger "Creating provider" $
46 provider <- timed logger "Creating provider" $
47 fileResourceProvider configuration
47 fileResourceProvider configuration
48
48
src/Hakyll/Core/Store.hs+32−17
@@ -9,6 +9,7 @@ module Hakyll.Core.Store
9 , storeGet
9 , storeGet
10 ) where
10 ) where
11
11
12+import Control.Applicative ((<$>))
12import Control.Concurrent.MVar (MVar, newMVar, readMVar, modifyMVar_)
13import Control.Concurrent.MVar (MVar, newMVar, readMVar, modifyMVar_)
13import System.FilePath ((</>))
14import System.FilePath ((</>))
14import System.Directory (doesFileExist)
15import System.Directory (doesFileExist)
@@ -39,14 +40,16 @@ data Store = Store
39 { -- | All items are stored on the filesystem
40 { -- | All items are stored on the filesystem
40 storeDirectory :: FilePath
41 storeDirectory :: FilePath
41 , -- | And some items are also kept in-memory
42 , -- | And some items are also kept in-memory
42− storeMap :: MVar (Map FilePath Storable)
43+ storeMap :: Maybe (MVar (Map FilePath Storable))
43 }
44 }
44
45
45-- | Initialize the store
46-- | Initialize the store
46--
47--
47−makeStore :: FilePath -> IO Store
48+makeStore :: Bool -- ^ Use in-memory caching
49+ -> FilePath -- ^ Directory to use for hard disk storage
50+ -> IO Store -- ^ Store
48−makeStore directory = do
51+makeStore inMemory directory = do
49− mvar <- newMVar M.empty
52+ mvar <- if inMemory then Just <$> newMVar M.empty else return Nothing
50 return Store
53 return Store
51 { storeDirectory = directory
54 { storeDirectory = directory
52 , storeMap = mvar
55 , storeMap = mvar
@@ -54,9 +57,23 @@ makeStore directory = do
54
57
55-- | Auxiliary: add an item to the map
58-- | Auxiliary: add an item to the map
56--
59--
57−addToMap :: (Binary a, Typeable a) => Store -> FilePath -> a -> IO ()
60+cacheInsert :: (Binary a, Typeable a) => Store -> FilePath -> a -> IO ()
58−addToMap store path value =
61+cacheInsert (Store _ Nothing) _ _ = return ()
62+cacheInsert (Store _ (Just mv)) path value =
59− modifyMVar_ (storeMap store) $ return . M.insert path (Storable value)
63+ modifyMVar_ mv $ return . M.insert path (Storable value)
64+
65+-- | Auxiliary: get an item from the cache
66+--
67+cacheLookup :: forall a. (Binary a, Typeable a)
68+ => Store -> FilePath -> IO (StoreGet a)
69+cacheLookup (Store _ Nothing) _ = return NotFound
70+cacheLookup (Store _ (Just mv)) path = do
71+ map' <- readMVar mv
72+ case M.lookup path map' of
73+ Nothing -> return NotFound
74+ Just (Storable s) -> return $ case cast s of
75+ Nothing -> WrongType (typeOf s) $ typeOf (undefined :: a)
76+ Just s' -> Found s'
60
77
61-- | Create a path
78-- | Create a path
62--
79--
@@ -73,31 +90,29 @@ storeSet :: (Binary a, Typeable a)
73storeSet store name identifier value = do
90storeSet store name identifier value = do
74 makeDirectories path
91 makeDirectories path
75 encodeFile path value
92 encodeFile path value
76− addToMap store path value
93+ cacheInsert store path value
77 where
94 where
78 path = makePath store name identifier
95 path = makePath store name identifier
79
96
80-- | Load an item
97-- | Load an item
81--
98--
82−storeGet :: forall a. (Binary a, Typeable a)
99+storeGet :: (Binary a, Typeable a)
83 => Store -> String -> Identifier a -> IO (StoreGet a)
100 => Store -> String -> Identifier a -> IO (StoreGet a)
84storeGet store name identifier = do
101storeGet store name identifier = do
85 -- First check the in-memory map
102 -- First check the in-memory map
86− map' <- readMVar $ storeMap store
103+ mv <- cacheLookup store path
87− case M.lookup path map' of
104+ case mv of
88− -- Found in the in-memory map
89− Just (Storable s) -> return $ case cast s of
90− Nothing -> WrongType (typeOf s) $ typeOf (undefined :: a)
91− Just s' -> Found s'
92 -- Not found in the map, try the filesystem
105 -- Not found in the map, try the filesystem
93− Nothing -> do
106+ NotFound -> do
94 exists <- doesFileExist path
107 exists <- doesFileExist path
95 if not exists
108 if not exists
96 -- Not found in the filesystem either
109 -- Not found in the filesystem either
97 then return NotFound
110 then return NotFound
98 -- Found in the filesystem
111 -- Found in the filesystem
99 else do v <- decodeFile path
112 else do v <- decodeFile path
100− addToMap store path v
113+ cacheInsert store path v
101 return $ Found v
114 return $ Found v
115+ -- Found in the in-memory map, just return
116+ s -> return s
102 where
117 where
103 path = makePath store name identifier
118 path = makePath store name identifier
tests/TestSuite/Util.hs+1−1
@@ -28,7 +28,7 @@ fromAssertions name = zipWith testCase names
28-- | Create a store for testing
28-- | Create a store for testing
29--
29--
30makeStoreTest :: IO Store
30makeStoreTest :: IO Store
31−makeStoreTest = makeStore "_store"
31+makeStoreTest = makeStore True "_store"
32
32
33-- | Testing for 'runCompilerJob'
33-- | Testing for 'runCompilerJob'
34--
34--