-- | A store for stroing and retreiving items--{-# LANGUAGE ExistentialQuantification, ScopedTypeVariables #-}moduleHakyll.Core.Store(Store,StoreGet(..),makeStore,storeSet,storeGet)whereimportControl.Concurrent.MVar(MVar,newMVar,readMVar,modifyMVar_)importSystem.FilePath((</>))importSystem.Directory(doesFileExist)importData.Maybe(fromMaybe)importData.Map(Map)importqualifiedData.MapasMimportData.Binary(Binary,encodeFile,decodeFile)importData.Typeable(Typeable,TypeRep,cast,typeOf)importHakyll.Core.IdentifierimportHakyll.Core.Util.File-- | Items we can store--dataStorable=foralla.(Binarya,Typeablea)=>Storablea-- | Result when an item from the store--dataStoreGeta=Founda|NotFound|WrongTypeTypeRepTypeRepderiving(Show,Eq)-- | Data structure used for the store--dataStore=Store{-- | All items are stored on the filesystemstoreDirectory::FilePath,-- | And some items are also kept in-memorystoreMap::MVar(MapFilePathStorable)}-- | Initialize the store--makeStore::FilePath->IOStoremakeStoredirectory=domvar<-newMVarM.emptyreturnStore{storeDirectory=directory,storeMap=mvar}-- | Auxiliary: add an item to the map--addToMap::(Binarya,Typeablea)=>Store->FilePath->a->IO()addToMapstorepathvalue=modifyMVar_(storeMapstore)$return.M.insertpath(Storablevalue)-- | Create a path--makePath::Store->String->Identifier->FilePathmakePathstorenameidentifier=storeDirectorystore</>name</>group</>toFilePathidentifier</>"hakyllstore"wheregroup=fromMaybe""$identifierGroupidentifier-- | Store an item--storeSet::(Binarya,Typeablea)=>Store->String->Identifier->a->IO()storeSetstorenameidentifiervalue=domakeDirectoriespathencodeFilepathvalueaddToMapstorepathvaluewherepath=makePathstorenameidentifier-- | Load an item--storeGet::foralla.(Binarya,Typeablea)=>Store->String->Identifier->IO(StoreGeta)storeGetstorenameidentifier=do-- First check the in-memory mapmap'<-readMVar$storeMapstorecaseM.lookuppathmap'of-- Found in the in-memory mapJust(Storables)->return$casecastsofNothing->WrongType(typeOfs)$typeOf(undefined::a)Justs'->Founds'-- Not found in the map, try the filesystemNothing->doexists<-doesFileExistpathifnotexists-- Not found in the filesystem eitherthenreturnNotFound-- Found in the filesystemelsedov<-decodeFilepathaddToMapstorepathvreturn$Foundvwherepath=makePathstorenameidentifier