on master help sign in
Use mtime instead of hashing files, much faster
commitd34d56b10e14e41ad303e6c5d3daef6970af65c2 authorJasper Van der Jeugt <m@jaspervdj.be> dateWed 6 Feb 2013, 20:50 (14 years ago) parent6e7f332
2 files changed+44−22
src/Hakyll/Core/Provider/Modified.hs+36−22 src/Hakyll/Core/Store.hs+8
src/Hakyll/Core/Provider/Modified.hs+36−22
@@ -1,5 +1,6 @@
11--------------------------------------------------------------------------------
2−{-# LANGUAGE CPP #-}
2+{-# LANGUAGE CPP #-}
3+{-# LANGUAGE DeriveDataTypeable #-}
34module Hakyll.Core.Provider.Modified
45 ( resourceModified
56 , resourceModificationTime
@@ -9,12 +10,12 @@ module Hakyll.Core.Provider.Modified
910--------------------------------------------------------------------------------
1011import Control.Applicative ((<$>), (<*>))
1112import Control.Monad (when)
12−import qualified Crypto.Hash.MD5 as MD5
13−import qualified Data.ByteString as B
14−import qualified Data.ByteString.Lazy as BL
13+import Data.Binary (Binary (..))
1514import Data.IORef
1615import qualified Data.Map as M
17−import Data.Time (UTCTime)
16+import Data.Time (Day (..), UTCTime (..),
17+ secondsToDiffTime)
18+import Data.Typeable (Typeable)
1819import System.Directory (getModificationTime)
1920
2021
@@ -48,7 +49,7 @@ resourceModified p r
4849 -- Check if the actual file was modified, and do a recursive
4950 -- call to check if the metadata file was modified
5051 m <- (||)
51− <$> fileDigestModified store filePath
52+ <$> fileModified store filePath
5253 <*> resourceModified p (resourceMetadataResource r)
5354 modifyIORef cacheRef (M.insert normalized m)
5455
@@ -65,37 +66,50 @@ resourceModified p r
6566
6667
6768--------------------------------------------------------------------------------
68−-- | Utility: Check if a the digest of a file was modified
69−fileDigestModified :: Store -> FilePath -> IO Bool
70−fileDigestModified store fp = do
71− -- Get the latest seen digest from the store, and calculate the current
72− -- digest for the
73− lastDigest <- Store.get store key
74− newDigest <- fileDigest fp
75− if Store.Found newDigest == lastDigest
69+-- | Utility: Check if a file was modified recently
70+fileModified :: Store -> FilePath -> IO Bool
71+fileModified store fp = do
72+ lastModified <- Store.get store key
73+ newModified <- BinaryTime <$> fileModificationTime fp
74+ if maybe False (>= newModified) (Store.toMaybe lastModified)
7675 -- All is fine, not modified
7776 then return False
7877 -- Resource modified; store new digest
7978 else do
80− Store.set store key newDigest
79+ Store.set store key newModified
8180 return True
8281 where
8382 key = ["Hakyll.Core.Resource.Provider.fileModified", fp]
8483
8584
8685--------------------------------------------------------------------------------
87−-- | Utility: Retrieve a digest for a given file
88−fileDigest :: FilePath -> IO B.ByteString
89−fileDigest = fmap MD5.hashlazy . BL.readFile
86+resourceModificationTime :: Provider -> Identifier -> IO UTCTime
87+resourceModificationTime p i = fileModificationTime $ resourceFilePath p i
9088
9189
9290--------------------------------------------------------------------------------
93−resourceModificationTime :: Provider -> Identifier -> IO UTCTime
94−resourceModificationTime p i = do
91+fileModificationTime :: FilePath -> IO UTCTime
92+fileModificationTime fp = do
9593#if MIN_VERSION_directory(1,2,0)
96− getModificationTime $ resourceFilePath p i
94+ getModificationTime fp
9795#else
98− ct <- toCalendarTime =<< getModificationTime (resourceFilePath p i)
96+ ct <- toCalendarTime =<< getModificationTime fp
9997 let str = formatCalendarTime defaultTimeLocale "%s" ct
10098 return $ readTime defaultTimeLocale "%s" str
10199#endif
100+
101+
102+--------------------------------------------------------------------------------
103+-- | Because UTCTime doesn't have a Binary instance...
104+newtype BinaryTime = BinaryTime UTCTime
105+ deriving (Eq, Ord, Typeable)
106+
107+
108+--------------------------------------------------------------------------------
109+instance Binary BinaryTime where
110+ put (BinaryTime (UTCTime (ModifiedJulianDay d) dt)) =
111+ put d >> put (floor dt :: Integer)
112+
113+ get = fmap BinaryTime $ UTCTime
114+ <$> (ModifiedJulianDay <$> get)
115+ <*> (secondsToDiffTime <$> get)
src/Hakyll/Core/Store.hs+8
@@ -5,6 +5,7 @@
55module Hakyll.Core.Store
66 ( Store
77 , Result (..)
8+ , toMaybe
89 , new
910 , set
1011 , get
@@ -53,6 +54,13 @@ data Result a
5354 deriving (Show, Eq)
5455
5556
57+--------------------------------------------------------------------------------
58+-- | Convert result to 'Maybe'
59+toMaybe :: Result a -> Maybe a
60+toMaybe (Found x) = Just x
61+toMaybe _ = Nothing
62+
63+
5664--------------------------------------------------------------------------------
5765-- | Initialize the store
5866new :: Bool -- ^ Use in-memory caching