summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Hakyll/Core/Resource/Provider.hs25
-rw-r--r--src/Hakyll/Core/Resource/Provider/File.hs6
-rw-r--r--src/Hakyll/Core/Run.hs4
3 files changed, 31 insertions, 4 deletions
diff --git a/src/Hakyll/Core/Resource/Provider.hs b/src/Hakyll/Core/Resource/Provider.hs
index 377b029..90e93f8 100644
--- a/src/Hakyll/Core/Resource/Provider.hs
+++ b/src/Hakyll/Core/Resource/Provider.hs
@@ -17,8 +17,11 @@ module Hakyll.Core.Resource.Provider
, resourceModified
) where
+import Control.Concurrent (MVar, readMVar, modifyMVar_)
import Control.Monad ((<=<))
import Data.Word (Word8)
+import Data.Map (Map)
+import qualified Data.Map as M
import qualified Data.ByteString.Lazy as LB
import OpenSSL.Digest.ByteString.Lazy (digest)
@@ -37,6 +40,8 @@ data ResourceProvider = ResourceProvider
resourceString :: Resource -> IO String
, -- | Retrieve a certain resource as lazy bytestring
resourceLazyByteString :: Resource -> IO LB.ByteString
+ , -- | Cache keeping track of modified items
+ resourceModifiedCache :: MVar (Map Resource Bool)
}
-- | Check if a given identifier has a resource
@@ -53,6 +58,24 @@ resourceDigest provider = digest MD5 <=< resourceLazyByteString provider
--
resourceModified :: ResourceProvider -> Resource -> Store -> IO Bool
resourceModified provider resource store = do
+ cache <- readMVar mvar
+ case M.lookup resource cache of
+ -- Already in the cache
+ Just m -> return m
+ -- Not yet in the cache, check digests (if it exists)
+ Nothing -> do
+ m <- if resourceExists provider (unResource resource)
+ then digestModified provider resource store
+ else return False
+ modifyMVar_ mvar (return . M.insert resource m)
+ return m
+ where
+ mvar = resourceModifiedCache provider
+
+-- | Check if a resource digest was modified
+--
+digestModified :: ResourceProvider -> Resource -> Store -> IO Bool
+digestModified provider resource store = do
-- Get the latest seen digest from the store
lastDigest <- storeGet store itemName $ unResource resource
-- Calculate the digest for the resource
@@ -65,4 +88,4 @@ resourceModified provider resource store = do
else do storeSet store itemName (unResource resource) newDigest
return True
where
- itemName = "Hakyll.Core.ResourceProvider.resourceModified"
+ itemName = "Hakyll.Core.ResourceProvider.digestModified"
diff --git a/src/Hakyll/Core/Resource/Provider/File.hs b/src/Hakyll/Core/Resource/Provider/File.hs
index a795fac..953d61c 100644
--- a/src/Hakyll/Core/Resource/Provider/File.hs
+++ b/src/Hakyll/Core/Resource/Provider/File.hs
@@ -5,6 +5,8 @@ module Hakyll.Core.Resource.Provider.File
) where
import Control.Applicative ((<$>))
+import Control.Concurrent (newMVar)
+import qualified Data.Map as M
import qualified Data.ByteString.Lazy as LB
@@ -22,9 +24,13 @@ fileResourceProvider configuration = do
list <- map parseIdentifier . filter (not . ignoreFile configuration) <$>
getRecursiveContents False "."
+ -- MVar for the cache
+ mvar <- newMVar M.empty
+
-- Construct a resource provider
return ResourceProvider
{ resourceList = map Resource list
, resourceString = readFile . toFilePath . unResource
, resourceLazyByteString = LB.readFile . toFilePath . unResource
+ , resourceModifiedCache = mvar
}
diff --git a/src/Hakyll/Core/Run.hs b/src/Hakyll/Core/Run.hs
index 8e1ba6d..54bb104 100644
--- a/src/Hakyll/Core/Run.hs
+++ b/src/Hakyll/Core/Run.hs
@@ -100,9 +100,7 @@ modified :: ResourceProvider -- ^ Resource provider
-> [Identifier] -- ^ Identifiers to check
-> IO (Set Identifier) -- ^ Modified resources
modified provider store ids = fmap S.fromList $ flip filterM ids $ \id' ->
- if resourceExists provider id'
- then resourceModified provider (Resource id') store
- else return False
+ resourceModified provider (Resource id') store
-- | Add a number of compilers and continue using these compilers
--