summaryrefslogtreecommitdiff
path: root/src/Hakyll/Core
diff options
context:
space:
mode:
authorJasper Van der Jeugt <jaspervdj@gmail.com>2011-04-06 09:30:24 +0200
committerJasper Van der Jeugt <jaspervdj@gmail.com>2011-04-06 09:30:24 +0200
commit3d2b2506d040546d74e83f6d9b8b4e0c45026f09 (patch)
tree60e5b351ac6e3b08fadce7b699aa734b1c6f1cbc /src/Hakyll/Core
parent015663657ceca7b168bf7d91fbc2fccc41c40904 (diff)
downloadhakyll-3d2b2506d040546d74e83f6d9b8b4e0c45026f09.tar.gz
Move modified cache to resource provider
Currently, it's kept twice: in Run and in the Provider. On the long term, it should be migrated entirely to the Provider, this can be done when the new dependency manager is finished.
Diffstat (limited to 'src/Hakyll/Core')
-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
--