module Agda.Utils.Hash where
import Data.ByteString as B
import Data.Word
import qualified Data.Hash as H
import qualified Data.List as L
import Data.Digest.Murmur64
import qualified Data.Text.Encoding as T
import Data.Text.Lazy (Text)
import qualified Data.Text.Lazy as T
import Agda.Utils.FileName
import Agda.Utils.IO.UTF8 (readTextFile)
type Hash = Word64
hashByteString :: ByteString -> Hash
hashByteString :: ByteString -> Hash
hashByteString = Hash -> Hash
H.asWord64 (Hash -> Hash) -> (ByteString -> Hash) -> ByteString -> Hash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Hash -> Word8 -> Hash) -> Hash -> ByteString -> Hash
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
B.foldl' (\Hash
h Word8
b -> Hash -> Hash -> Hash
H.combine Hash
h (Word8 -> Hash
H.hashWord8 Word8
b)) (Word8 -> Hash
H.hashWord8 Word8
0)
hashTextFile :: AbsolutePath -> IO Hash
hashTextFile :: AbsolutePath -> IO Hash
hashTextFile AbsolutePath
file = Text -> Hash
hashText (Text -> Hash) -> IO Text -> IO Hash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO Text
readTextFile (AbsolutePath -> FilePath
filePath AbsolutePath
file)
hashText :: Text -> Hash
hashText :: Text -> Hash
hashText = ByteString -> Hash
hashByteString (ByteString -> Hash) -> (Text -> ByteString) -> Text -> Hash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> (Text -> Text) -> Text -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.toStrict
combineHashes :: [Hash] -> Hash
combineHashes :: [Hash] -> Hash
combineHashes [Hash]
hs = Hash -> Hash
H.asWord64 (Hash -> Hash) -> Hash -> Hash
forall a b. (a -> b) -> a -> b
$ (Hash -> Hash -> Hash) -> Hash -> [Hash] -> Hash
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' Hash -> Hash -> Hash
H.combine (Word8 -> Hash
H.hashWord8 Word8
0) ([Hash] -> Hash) -> [Hash] -> Hash
forall a b. (a -> b) -> a -> b
$ (Hash -> Hash) -> [Hash] -> [Hash]
forall a b. (a -> b) -> [a] -> [b]
L.map Hash -> Hash
forall a. Hashable a => a -> Hash
H.hash [Hash]
hs
hashString :: String -> Word64
hashString :: FilePath -> Hash
hashString = Hash64 -> Hash
asWord64 (Hash64 -> Hash) -> (FilePath -> Hash64) -> FilePath -> Hash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Hash64
forall a. Hashable64 a => a -> Hash64
hash64