{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}

-- |
-- Module: Data.Hash.FNV1
-- Copyright: Copyright © 2021 Lars Kuhtz <lakuhtz@gmail.com>
-- License: MIT
-- Maintainer: Lars Kuhtz <lakuhtz@gmail.com>
-- Stability: experimental
--
-- The primitive versions are usually not more efficient than the version with
-- explicit word sizes for the respective host architecture.
--
module Data.Hash.FNV1
(
-- * Fnv1 64 bit
  Fnv164Hash(..)
, Fnv164Context
, fnv164Initialize
, fnv164Update
, fnv164Finalize
, fnv164


-- * Fnv1a 64 bit
, Fnv1a64Hash(..)
, Fnv1a64Context
, fnv1a64Initialize
, fnv1a64Update
, fnv1a64Finalize
, fnv1a64

-- * Fnv1 32 bit
, Fnv132Hash(..)
, Fnv132Context
, fnv132Initialize
, fnv132Update
, fnv132Finalize
, fnv132

-- * Fnv1a 32 bit
, Fnv1a32Hash(..)
, Fnv1a32Context
, fnv1a32Initialize
, fnv1a32Update
, fnv1a32Finalize
, fnv1a32

-- * Fnv1 Host Wordsize
, Fnv1Hash(..)
, Fnv1Context
, fnv1Initialize
, fnv1Update
, fnv1Finalize
, fnv1

-- * Fnv1a Host Wordsize
, Fnv1aHash(..)
, Fnv1aContext
, fnv1aInitialize
, fnv1aUpdate
, fnv1aFinalize
, fnv1a

-- * Utils
, module Data.Hash.Class.Pure

-- * Low-Level
-- ** 64 bit

, fnv1_64
, fnv1_64_
, fnv1a_64
, fnv1a_64_

-- ** 32 bit
, fnv1_32
, fnv1_32_
, fnv1a_32
, fnv1a_32_

-- ** Host word size
, fnv1_host
, fnv1_host_
, fnv1Primitive
, fnv1Primitive_

, fnv1a_host
, fnv1a_host_
, fnv1aPrimitive
, fnv1aPrimitive_

-- ** Internal Constants
, fnvPrime
, fnvPrime32
, fnvPrime64

, fnvOffsetBasis
, fnvOffsetBasis32
, fnvOffsetBasis64

) where

import Control.Monad

import Data.Bits
import Data.Word

import Foreign.Ptr
import Foreign.Storable

import GHC.Exts
import GHC.IO

-- internal modules

import Data.Hash.Class.Pure

-- -------------------------------------------------------------------------- --
-- Fnv1 64 bit

newtype Fnv164Context = Fnv164Context Word64

newtype Fnv164Hash = Fnv164Hash Word64
    deriving (Int -> Fnv164Hash -> ShowS
[Fnv164Hash] -> ShowS
Fnv164Hash -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Fnv164Hash] -> ShowS
$cshowList :: [Fnv164Hash] -> ShowS
show :: Fnv164Hash -> String
$cshow :: Fnv164Hash -> String
showsPrec :: Int -> Fnv164Hash -> ShowS
$cshowsPrec :: Int -> Fnv164Hash -> ShowS
Show, Fnv164Hash -> Fnv164Hash -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Fnv164Hash -> Fnv164Hash -> Bool
$c/= :: Fnv164Hash -> Fnv164Hash -> Bool
== :: Fnv164Hash -> Fnv164Hash -> Bool
$c== :: Fnv164Hash -> Fnv164Hash -> Bool
Eq, Eq Fnv164Hash
Fnv164Hash -> Fnv164Hash -> Bool
Fnv164Hash -> Fnv164Hash -> Ordering
Fnv164Hash -> Fnv164Hash -> Fnv164Hash
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Fnv164Hash -> Fnv164Hash -> Fnv164Hash
$cmin :: Fnv164Hash -> Fnv164Hash -> Fnv164Hash
max :: Fnv164Hash -> Fnv164Hash -> Fnv164Hash
$cmax :: Fnv164Hash -> Fnv164Hash -> Fnv164Hash
>= :: Fnv164Hash -> Fnv164Hash -> Bool
$c>= :: Fnv164Hash -> Fnv164Hash -> Bool
> :: Fnv164Hash -> Fnv164Hash -> Bool
$c> :: Fnv164Hash -> Fnv164Hash -> Bool
<= :: Fnv164Hash -> Fnv164Hash -> Bool
$c<= :: Fnv164Hash -> Fnv164Hash -> Bool
< :: Fnv164Hash -> Fnv164Hash -> Bool
$c< :: Fnv164Hash -> Fnv164Hash -> Bool
compare :: Fnv164Hash -> Fnv164Hash -> Ordering
$ccompare :: Fnv164Hash -> Fnv164Hash -> Ordering
Ord)

fnv164Initialize :: Fnv164Context
fnv164Initialize :: Fnv164Context
fnv164Initialize = Word64 -> Fnv164Context
Fnv164Context Word64
fnvOffsetBasis64
{-# INLINE fnv164Initialize #-}

fnv164Update :: Fnv164Context -> Ptr Word8 -> Int -> IO Fnv164Context
fnv164Update :: Fnv164Context -> Ptr Word8 -> Int -> IO Fnv164Context
fnv164Update (Fnv164Context !Word64
ctx) !Ptr Word8
ptr !Int
n =
    Word64 -> Fnv164Context
Fnv164Context forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Ptr Word8 -> Int -> Word64 -> IO Word64
fnv1_64_ Ptr Word8
ptr Int
n Word64
ctx
{-# INLINE fnv164Update #-}

fnv164Finalize :: Fnv164Context -> Fnv164Hash
fnv164Finalize :: Fnv164Context -> Fnv164Hash
fnv164Finalize (Fnv164Context !Word64
ctx) = Word64 -> Fnv164Hash
Fnv164Hash Word64
ctx
{-# INLINE fnv164Finalize #-}

fnv164 :: Ptr Word8 -> Int -> IO Fnv164Hash
fnv164 :: Ptr Word8 -> Int -> IO Fnv164Hash
fnv164 !Ptr Word8
ptr !Int
n = Fnv164Context -> Fnv164Hash
fnv164Finalize forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Fnv164Context -> Ptr Word8 -> Int -> IO Fnv164Context
fnv164Update Fnv164Context
fnv164Initialize Ptr Word8
ptr Int
n
{-# INLINE fnv164 #-}

instance IncrementalHash Fnv164Hash where
    type Context Fnv164Hash = Fnv164Context
    update :: Context Fnv164Hash -> Ptr Word8 -> Int -> IO (Context Fnv164Hash)
update = Fnv164Context -> Ptr Word8 -> Int -> IO Fnv164Context
fnv164Update
    finalize :: Context Fnv164Hash -> Fnv164Hash
finalize = Fnv164Context -> Fnv164Hash
fnv164Finalize

    {-# INLINE update #-}
    {-# INLINE finalize #-}

instance Hash Fnv164Hash where
    initialize :: Context Fnv164Hash
initialize = Fnv164Context
fnv164Initialize
    {-# INLINE initialize #-}

-- -------------------------------------------------------------------------- --
-- Fnv1a 64 bit

newtype Fnv1a64Context = Fnv1a64Context Word64

newtype Fnv1a64Hash = Fnv1a64Hash Word64
    deriving (Int -> Fnv1a64Hash -> ShowS
[Fnv1a64Hash] -> ShowS
Fnv1a64Hash -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Fnv1a64Hash] -> ShowS
$cshowList :: [Fnv1a64Hash] -> ShowS
show :: Fnv1a64Hash -> String
$cshow :: Fnv1a64Hash -> String
showsPrec :: Int -> Fnv1a64Hash -> ShowS
$cshowsPrec :: Int -> Fnv1a64Hash -> ShowS
Show, Fnv1a64Hash -> Fnv1a64Hash -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
$c/= :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
== :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
$c== :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
Eq, Eq Fnv1a64Hash
Fnv1a64Hash -> Fnv1a64Hash -> Bool
Fnv1a64Hash -> Fnv1a64Hash -> Ordering
Fnv1a64Hash -> Fnv1a64Hash -> Fnv1a64Hash
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Fnv1a64Hash -> Fnv1a64Hash -> Fnv1a64Hash
$cmin :: Fnv1a64Hash -> Fnv1a64Hash -> Fnv1a64Hash
max :: Fnv1a64Hash -> Fnv1a64Hash -> Fnv1a64Hash
$cmax :: Fnv1a64Hash -> Fnv1a64Hash -> Fnv1a64Hash
>= :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
$c>= :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
> :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
$c> :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
<= :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
$c<= :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
< :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
$c< :: Fnv1a64Hash -> Fnv1a64Hash -> Bool
compare :: Fnv1a64Hash -> Fnv1a64Hash -> Ordering
$ccompare :: Fnv1a64Hash -> Fnv1a64Hash -> Ordering
Ord)

fnv1a64Initialize :: Fnv1a64Context
fnv1a64Initialize :: Fnv1a64Context
fnv1a64Initialize = Word64 -> Fnv1a64Context
Fnv1a64Context Word64
fnvOffsetBasis64
{-# INLINE fnv1a64Initialize #-}

fnv1a64Update :: Fnv1a64Context -> Ptr Word8 -> Int -> IO Fnv1a64Context
fnv1a64Update :: Fnv1a64Context -> Ptr Word8 -> Int -> IO Fnv1a64Context
fnv1a64Update (Fnv1a64Context !Word64
ctx) !Ptr Word8
ptr !Int
n =
    Word64 -> Fnv1a64Context
Fnv1a64Context forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Ptr Word8 -> Int -> Word64 -> IO Word64
fnv1a_64_ Ptr Word8
ptr Int
n Word64
ctx
{-# INLINE fnv1a64Update #-}

fnv1a64Finalize :: Fnv1a64Context -> Fnv1a64Hash
fnv1a64Finalize :: Fnv1a64Context -> Fnv1a64Hash
fnv1a64Finalize (Fnv1a64Context !Word64
ctx) = Word64 -> Fnv1a64Hash
Fnv1a64Hash Word64
ctx
{-# INLINE fnv1a64Finalize #-}

fnv1a64 :: Ptr Word8 -> Int -> IO Fnv1a64Hash
fnv1a64 :: Ptr Word8 -> Int -> IO Fnv1a64Hash
fnv1a64 !Ptr Word8
ptr !Int
n = Fnv1a64Context -> Fnv1a64Hash
fnv1a64Finalize forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Fnv1a64Context -> Ptr Word8 -> Int -> IO Fnv1a64Context
fnv1a64Update Fnv1a64Context
fnv1a64Initialize Ptr Word8
ptr Int
n
{-# INLINE fnv1a64 #-}

instance IncrementalHash Fnv1a64Hash where
    type Context Fnv1a64Hash = Fnv1a64Context
    update :: Context Fnv1a64Hash -> Ptr Word8 -> Int -> IO (Context Fnv1a64Hash)
update = Fnv1a64Context -> Ptr Word8 -> Int -> IO Fnv1a64Context
fnv1a64Update
    finalize :: Context Fnv1a64Hash -> Fnv1a64Hash
finalize = Fnv1a64Context -> Fnv1a64Hash
fnv1a64Finalize

    {-# INLINE update #-}
    {-# INLINE finalize #-}

instance Hash Fnv1a64Hash where
    initialize :: Context Fnv1a64Hash
initialize = Fnv1a64Context
fnv1a64Initialize
    {-# INLINE initialize #-}

-- -------------------------------------------------------------------------- --
-- Fnv1 32 bit

newtype Fnv132Context = Fnv132Context Word32

newtype Fnv132Hash = Fnv132Hash Word32
    deriving (Int -> Fnv132Hash -> ShowS
[Fnv132Hash] -> ShowS
Fnv132Hash -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Fnv132Hash] -> ShowS
$cshowList :: [Fnv132Hash] -> ShowS
show :: Fnv132Hash -> String
$cshow :: Fnv132Hash -> String
showsPrec :: Int -> Fnv132Hash -> ShowS
$cshowsPrec :: Int -> Fnv132Hash -> ShowS
Show, Fnv132Hash -> Fnv132Hash -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Fnv132Hash -> Fnv132Hash -> Bool
$c/= :: Fnv132Hash -> Fnv132Hash -> Bool
== :: Fnv132Hash -> Fnv132Hash -> Bool
$c== :: Fnv132Hash -> Fnv132Hash -> Bool
Eq, Eq Fnv132Hash
Fnv132Hash -> Fnv132Hash -> Bool
Fnv132Hash -> Fnv132Hash -> Ordering
Fnv132Hash -> Fnv132Hash -> Fnv132Hash
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Fnv132Hash -> Fnv132Hash -> Fnv132Hash
$cmin :: Fnv132Hash -> Fnv132Hash -> Fnv132Hash
max :: Fnv132Hash -> Fnv132Hash -> Fnv132Hash
$cmax :: Fnv132Hash -> Fnv132Hash -> Fnv132Hash
>= :: Fnv132Hash -> Fnv132Hash -> Bool
$c>= :: Fnv132Hash -> Fnv132Hash -> Bool
> :: Fnv132Hash -> Fnv132Hash -> Bool
$c> :: Fnv132Hash -> Fnv132Hash -> Bool
<= :: Fnv132Hash -> Fnv132Hash -> Bool
$c<= :: Fnv132Hash -> Fnv132Hash -> Bool
< :: Fnv132Hash -> Fnv132Hash -> Bool
$c< :: Fnv132Hash -> Fnv132Hash -> Bool
compare :: Fnv132Hash -> Fnv132Hash -> Ordering
$ccompare :: Fnv132Hash -> Fnv132Hash -> Ordering
Ord)

fnv132Initialize :: Fnv132Context
fnv132Initialize :: Fnv132Context
fnv132Initialize = Word32 -> Fnv132Context
Fnv132Context Word32
fnvOffsetBasis32
{-# INLINE fnv132Initialize #-}

fnv132Update :: Fnv132Context -> Ptr Word8 -> Int -> IO Fnv132Context
fnv132Update :: Fnv132Context -> Ptr Word8 -> Int -> IO Fnv132Context
fnv132Update (Fnv132Context !Word32
ctx) !Ptr Word8
ptr !Int
n =
    Word32 -> Fnv132Context
Fnv132Context forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Ptr Word8 -> Int -> Word32 -> IO Word32
fnv1_32_ Ptr Word8
ptr Int
n Word32
ctx
{-# INLINE fnv132Update #-}

fnv132Finalize :: Fnv132Context -> Fnv132Hash
fnv132Finalize :: Fnv132Context -> Fnv132Hash
fnv132Finalize (Fnv132Context !Word32
ctx) = Word32 -> Fnv132Hash
Fnv132Hash Word32
ctx
{-# INLINE fnv132Finalize #-}

fnv132 :: Ptr Word8 -> Int -> IO Fnv132Hash
fnv132 :: Ptr Word8 -> Int -> IO Fnv132Hash
fnv132 !Ptr Word8
ptr !Int
n = Fnv132Context -> Fnv132Hash
fnv132Finalize forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Fnv132Context -> Ptr Word8 -> Int -> IO Fnv132Context
fnv132Update Fnv132Context
fnv132Initialize Ptr Word8
ptr Int
n
{-# INLINE fnv132 #-}

instance IncrementalHash Fnv132Hash where
    type Context Fnv132Hash = Fnv132Context
    update :: Context Fnv132Hash -> Ptr Word8 -> Int -> IO (Context Fnv132Hash)
update = Fnv132Context -> Ptr Word8 -> Int -> IO Fnv132Context
fnv132Update
    finalize :: Context Fnv132Hash -> Fnv132Hash
finalize = Fnv132Context -> Fnv132Hash
fnv132Finalize

    {-# INLINE update #-}
    {-# INLINE finalize #-}

instance Hash Fnv132Hash where
    initialize :: Context Fnv132Hash
initialize = Fnv132Context
fnv132Initialize
    {-# INLINE initialize #-}

-- -------------------------------------------------------------------------- --
-- Fnv1a 32 bit

newtype Fnv1a32Context = Fnv1a32Context Word32

newtype Fnv1a32Hash = Fnv1a32Hash Word32
    deriving (Int -> Fnv1a32Hash -> ShowS
[Fnv1a32Hash] -> ShowS
Fnv1a32Hash -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Fnv1a32Hash] -> ShowS
$cshowList :: [Fnv1a32Hash] -> ShowS
show :: Fnv1a32Hash -> String
$cshow :: Fnv1a32Hash -> String
showsPrec :: Int -> Fnv1a32Hash -> ShowS
$cshowsPrec :: Int -> Fnv1a32Hash -> ShowS
Show, Fnv1a32Hash -> Fnv1a32Hash -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
$c/= :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
== :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
$c== :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
Eq, Eq Fnv1a32Hash
Fnv1a32Hash -> Fnv1a32Hash -> Bool
Fnv1a32Hash -> Fnv1a32Hash -> Ordering
Fnv1a32Hash -> Fnv1a32Hash -> Fnv1a32Hash
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Fnv1a32Hash -> Fnv1a32Hash -> Fnv1a32Hash
$cmin :: Fnv1a32Hash -> Fnv1a32Hash -> Fnv1a32Hash
max :: Fnv1a32Hash -> Fnv1a32Hash -> Fnv1a32Hash
$cmax :: Fnv1a32Hash -> Fnv1a32Hash -> Fnv1a32Hash
>= :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
$c>= :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
> :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
$c> :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
<= :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
$c<= :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
< :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
$c< :: Fnv1a32Hash -> Fnv1a32Hash -> Bool
compare :: Fnv1a32Hash -> Fnv1a32Hash -> Ordering
$ccompare :: Fnv1a32Hash -> Fnv1a32Hash -> Ordering
Ord)

fnv1a32Initialize :: Fnv1a32Context
fnv1a32Initialize :: Fnv1a32Context
fnv1a32Initialize = Word32 -> Fnv1a32Context
Fnv1a32Context Word32
fnvOffsetBasis32
{-# INLINE fnv1a32Initialize #-}

fnv1a32Update :: Fnv1a32Context -> Ptr Word8 -> Int -> IO Fnv1a32Context
fnv1a32Update :: Fnv1a32Context -> Ptr Word8 -> Int -> IO Fnv1a32Context
fnv1a32Update (Fnv1a32Context !Word32
ctx) !Ptr Word8
ptr !Int
n =
    Word32 -> Fnv1a32Context
Fnv1a32Context forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Ptr Word8 -> Int -> Word32 -> IO Word32
fnv1a_32_ Ptr Word8
ptr Int
n Word32
ctx
{-# INLINE fnv1a32Update #-}

fnv1a32Finalize :: Fnv1a32Context -> Fnv1a32Hash
fnv1a32Finalize :: Fnv1a32Context -> Fnv1a32Hash
fnv1a32Finalize (Fnv1a32Context !Word32
ctx) = Word32 -> Fnv1a32Hash
Fnv1a32Hash Word32
ctx
{-# INLINE fnv1a32Finalize #-}

fnv1a32 :: Ptr Word8 -> Int -> IO Fnv1a32Hash
fnv1a32 :: Ptr Word8 -> Int -> IO Fnv1a32Hash
fnv1a32 !Ptr Word8
ptr !Int
n = Fnv1a32Context -> Fnv1a32Hash
fnv1a32Finalize forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Fnv1a32Context -> Ptr Word8 -> Int -> IO Fnv1a32Context
fnv1a32Update Fnv1a32Context
fnv1a32Initialize Ptr Word8
ptr Int
n
{-# INLINE fnv1a32 #-}

instance IncrementalHash Fnv1a32Hash where
    type Context Fnv1a32Hash = Fnv1a32Context
    update :: Context Fnv1a32Hash -> Ptr Word8 -> Int -> IO (Context Fnv1a32Hash)
update = Fnv1a32Context -> Ptr Word8 -> Int -> IO Fnv1a32Context
fnv1a32Update
    finalize :: Context Fnv1a32Hash -> Fnv1a32Hash
finalize = Fnv1a32Context -> Fnv1a32Hash
fnv1a32Finalize

    {-# INLINE update #-}
    {-# INLINE finalize #-}

instance Hash Fnv1a32Hash where
    initialize :: Context Fnv1a32Hash
initialize = Fnv1a32Context
fnv1a32Initialize
    {-# INLINE initialize #-}

-- -------------------------------------------------------------------------- --
-- Fnv1 Host Wordsize

newtype Fnv1Context = Fnv1Context Word

newtype Fnv1Hash = Fnv1Hash Word
    deriving (Int -> Fnv1Hash -> ShowS
[Fnv1Hash] -> ShowS
Fnv1Hash -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Fnv1Hash] -> ShowS
$cshowList :: [Fnv1Hash] -> ShowS
show :: Fnv1Hash -> String
$cshow :: Fnv1Hash -> String
showsPrec :: Int -> Fnv1Hash -> ShowS
$cshowsPrec :: Int -> Fnv1Hash -> ShowS
Show, Fnv1Hash -> Fnv1Hash -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Fnv1Hash -> Fnv1Hash -> Bool
$c/= :: Fnv1Hash -> Fnv1Hash -> Bool
== :: Fnv1Hash -> Fnv1Hash -> Bool
$c== :: Fnv1Hash -> Fnv1Hash -> Bool
Eq, Eq Fnv1Hash
Fnv1Hash -> Fnv1Hash -> Bool
Fnv1Hash -> Fnv1Hash -> Ordering
Fnv1Hash -> Fnv1Hash -> Fnv1Hash
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Fnv1Hash -> Fnv1Hash -> Fnv1Hash
$cmin :: Fnv1Hash -> Fnv1Hash -> Fnv1Hash
max :: Fnv1Hash -> Fnv1Hash -> Fnv1Hash
$cmax :: Fnv1Hash -> Fnv1Hash -> Fnv1Hash
>= :: Fnv1Hash -> Fnv1Hash -> Bool
$c>= :: Fnv1Hash -> Fnv1Hash -> Bool
> :: Fnv1Hash -> Fnv1Hash -> Bool
$c> :: Fnv1Hash -> Fnv1Hash -> Bool
<= :: Fnv1Hash -> Fnv1Hash -> Bool
$c<= :: Fnv1Hash -> Fnv1Hash -> Bool
< :: Fnv1Hash -> Fnv1Hash -> Bool
$c< :: Fnv1Hash -> Fnv1Hash -> Bool
compare :: Fnv1Hash -> Fnv1Hash -> Ordering
$ccompare :: Fnv1Hash -> Fnv1Hash -> Ordering
Ord)

fnv1Initialize :: Fnv1Context
fnv1Initialize :: Fnv1Context
fnv1Initialize = Word -> Fnv1Context
Fnv1Context Word
fnvOffsetBasis
{-# INLINE fnv1Initialize #-}

fnv1Update :: Fnv1Context -> Ptr Word8 -> Int -> IO Fnv1Context
fnv1Update :: Fnv1Context -> Ptr Word8 -> Int -> IO Fnv1Context
fnv1Update (Fnv1Context !Word
ctx) !Ptr Word8
ptr !Int
n =
    Word -> Fnv1Context
Fnv1Context forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Ptr Word8 -> Int -> Word -> IO Word
fnv1_host_ Ptr Word8
ptr Int
n Word
ctx
{-# INLINE fnv1Update #-}

fnv1Finalize :: Fnv1Context -> Fnv1Hash
fnv1Finalize :: Fnv1Context -> Fnv1Hash
fnv1Finalize (Fnv1Context !Word
ctx) = Word -> Fnv1Hash
Fnv1Hash Word
ctx
{-# INLINE fnv1Finalize #-}

fnv1 :: Ptr Word8 -> Int -> IO Fnv1Hash
fnv1 :: Ptr Word8 -> Int -> IO Fnv1Hash
fnv1 !Ptr Word8
ptr !Int
n = Fnv1Context -> Fnv1Hash
fnv1Finalize forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Fnv1Context -> Ptr Word8 -> Int -> IO Fnv1Context
fnv1Update Fnv1Context
fnv1Initialize Ptr Word8
ptr Int
n
{-# INLINE fnv1 #-}

instance IncrementalHash Fnv1Hash where
    type Context Fnv1Hash = Fnv1Context
    update :: Context Fnv1Hash -> Ptr Word8 -> Int -> IO (Context Fnv1Hash)
update = Fnv1Context -> Ptr Word8 -> Int -> IO Fnv1Context
fnv1Update
    finalize :: Context Fnv1Hash -> Fnv1Hash
finalize = Fnv1Context -> Fnv1Hash
fnv1Finalize

    {-# INLINE update #-}
    {-# INLINE finalize #-}

instance Hash Fnv1Hash where
    initialize :: Context Fnv1Hash
initialize = Fnv1Context
fnv1Initialize
    {-# INLINE initialize #-}

-- -------------------------------------------------------------------------- --
-- Fnv1a Host Wordsize

newtype Fnv1aContext = Fnv1aContext Word

newtype Fnv1aHash = Fnv1aHash Word
    deriving (Int -> Fnv1aHash -> ShowS
[Fnv1aHash] -> ShowS
Fnv1aHash -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Fnv1aHash] -> ShowS
$cshowList :: [Fnv1aHash] -> ShowS
show :: Fnv1aHash -> String
$cshow :: Fnv1aHash -> String
showsPrec :: Int -> Fnv1aHash -> ShowS
$cshowsPrec :: Int -> Fnv1aHash -> ShowS
Show, Fnv1aHash -> Fnv1aHash -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Fnv1aHash -> Fnv1aHash -> Bool
$c/= :: Fnv1aHash -> Fnv1aHash -> Bool
== :: Fnv1aHash -> Fnv1aHash -> Bool
$c== :: Fnv1aHash -> Fnv1aHash -> Bool
Eq, Eq Fnv1aHash
Fnv1aHash -> Fnv1aHash -> Bool
Fnv1aHash -> Fnv1aHash -> Ordering
Fnv1aHash -> Fnv1aHash -> Fnv1aHash
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Fnv1aHash -> Fnv1aHash -> Fnv1aHash
$cmin :: Fnv1aHash -> Fnv1aHash -> Fnv1aHash
max :: Fnv1aHash -> Fnv1aHash -> Fnv1aHash
$cmax :: Fnv1aHash -> Fnv1aHash -> Fnv1aHash
>= :: Fnv1aHash -> Fnv1aHash -> Bool
$c>= :: Fnv1aHash -> Fnv1aHash -> Bool
> :: Fnv1aHash -> Fnv1aHash -> Bool
$c> :: Fnv1aHash -> Fnv1aHash -> Bool
<= :: Fnv1aHash -> Fnv1aHash -> Bool
$c<= :: Fnv1aHash -> Fnv1aHash -> Bool
< :: Fnv1aHash -> Fnv1aHash -> Bool
$c< :: Fnv1aHash -> Fnv1aHash -> Bool
compare :: Fnv1aHash -> Fnv1aHash -> Ordering
$ccompare :: Fnv1aHash -> Fnv1aHash -> Ordering
Ord)

fnv1aInitialize :: Fnv1aContext
fnv1aInitialize :: Fnv1aContext
fnv1aInitialize = Word -> Fnv1aContext
Fnv1aContext Word
fnvOffsetBasis
{-# INLINE fnv1aInitialize #-}

fnv1aUpdate :: Fnv1aContext -> Ptr Word8 -> Int -> IO Fnv1aContext
fnv1aUpdate :: Fnv1aContext -> Ptr Word8 -> Int -> IO Fnv1aContext
fnv1aUpdate (Fnv1aContext !Word
ctx) !Ptr Word8
ptr !Int
n =
    Word -> Fnv1aContext
Fnv1aContext forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Ptr Word8 -> Int -> Word -> IO Word
fnv1a_host_ Ptr Word8
ptr Int
n Word
ctx
{-# INLINE fnv1aUpdate #-}

fnv1aFinalize :: Fnv1aContext -> Fnv1aHash
fnv1aFinalize :: Fnv1aContext -> Fnv1aHash
fnv1aFinalize (Fnv1aContext !Word
ctx) = Word -> Fnv1aHash
Fnv1aHash Word
ctx
{-# INLINE fnv1aFinalize #-}

fnv1a :: Ptr Word8 -> Int -> IO Fnv1aHash
fnv1a :: Ptr Word8 -> Int -> IO Fnv1aHash
fnv1a !Ptr Word8
ptr !Int
n = Fnv1aContext -> Fnv1aHash
fnv1aFinalize forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Fnv1aContext -> Ptr Word8 -> Int -> IO Fnv1aContext
fnv1aUpdate Fnv1aContext
fnv1aInitialize Ptr Word8
ptr Int
n
{-# INLINE fnv1a #-}

instance IncrementalHash Fnv1aHash where
    type Context Fnv1aHash = Fnv1aContext
    update :: Context Fnv1aHash -> Ptr Word8 -> Int -> IO (Context Fnv1aHash)
update = Fnv1aContext -> Ptr Word8 -> Int -> IO Fnv1aContext
fnv1aUpdate
    finalize :: Context Fnv1aHash -> Fnv1aHash
finalize = Fnv1aContext -> Fnv1aHash
fnv1aFinalize

    {-# INLINE update #-}
    {-# INLINE finalize #-}

instance Hash Fnv1aHash where
    initialize :: Context Fnv1aHash
initialize = Fnv1aContext
fnv1aInitialize
    {-# INLINE initialize #-}

-- -------------------------------------------------------------------------- --
-- Low Level
-- -------------------------------------------------------------------------- --

-- -------------------------------------------------------------------------- --
-- Constants

fnvPrime32 :: Word32
fnvPrime32 :: Word32
fnvPrime32 = Word32
0x01000193
{-# INLINE fnvPrime32 #-}

fnvPrime64 :: Word64
fnvPrime64 :: Word64
fnvPrime64 = Word64
0x100000001b3
{-# INLINE fnvPrime64 #-}

fnvOffsetBasis32 :: Word32
fnvOffsetBasis32 :: Word32
fnvOffsetBasis32 = Word32
0x811c9dc5
{-# INLINE fnvOffsetBasis32 #-}

fnvOffsetBasis64 :: Word64
fnvOffsetBasis64 :: Word64
fnvOffsetBasis64 = Word64
0xcbf29ce484222325
{-# INLINE fnvOffsetBasis64 #-}

fnvPrime :: Word
#if defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH)
fnvPrime :: Word
fnvPrime = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
fnvPrime64
#elif defined(i386_HOST_ARCH)
fnvPrime = fromIntegral fvnPrime32
#else
fnvPrime = error "fnvPrime: unsupported hardware platform"
#endif
{-# INLINE fnvPrime #-}

fnvOffsetBasis :: Word
#if defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH)
fnvOffsetBasis :: Word
fnvOffsetBasis = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
fnvOffsetBasis64
#elif defined(i386_HOST_ARCH)
fnvOffsetBasis = fromIntegral fnvOffsetBasis32
#else
fnvOffsetBasis = error "fnvOffsetBasis: unsupported hardware platform"
#endif
{-# INLINE fnvOffsetBasis #-}

-- -------------------------------------------------------------------------- --
-- FNV1 64 bit

fnv1_64 :: Ptr Word8 -> Int -> IO Word64
fnv1_64 :: Ptr Word8 -> Int -> IO Word64
fnv1_64 !Ptr Word8
ptr !Int
n = Ptr Word8 -> Int -> Word64 -> IO Word64
fnv1_64_ Ptr Word8
ptr Int
n Word64
fnvOffsetBasis64
{-# INLINE fnv1_64 #-}

fnv1_64_ :: Ptr Word8 -> Int -> Word64 -> IO Word64
fnv1_64_ :: Ptr Word8 -> Int -> Word64 -> IO Word64
fnv1_64_ !Ptr Word8
ptr !Int
n !Word64
a = Word64 -> Int -> IO Word64
loop Word64
a Int
0
  where
    loop :: Word64 -> Int -> IO Word64
loop !Word64
acc !Int
i
        | Int
i forall a. Eq a => a -> a -> Bool
== Int
n = forall (m :: * -> *) a. Monad m => a -> m a
return Word64
acc
        | Bool
otherwise = do
            !Word8
x <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff @Word8 Ptr Word8
ptr Int
i
            Word64 -> Int -> IO Word64
loop ((Word64
fnvPrime64 forall a. Num a => a -> a -> a
* Word64
acc) forall a. Bits a => a -> a -> a
`xor` forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
x) (Int
i forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE fnv1_64_ #-}

-- -------------------------------------------------------------------------- --
-- FNV1a 64 bit

fnv1a_64 :: Ptr Word8 -> Int -> IO Word64
fnv1a_64 :: Ptr Word8 -> Int -> IO Word64
fnv1a_64 !Ptr Word8
ptr !Int
n = Ptr Word8 -> Int -> Word64 -> IO Word64
fnv1a_64_ Ptr Word8
ptr Int
n Word64
fnvOffsetBasis64
{-# INLINE fnv1a_64 #-}

fnv1a_64_ :: Ptr Word8 -> Int -> Word64 -> IO Word64
fnv1a_64_ :: Ptr Word8 -> Int -> Word64 -> IO Word64
fnv1a_64_ !Ptr Word8
ptr !Int
n !Word64
a = Word64 -> Int -> IO Word64
loop Word64
a Int
0
  where
    loop :: Word64 -> Int -> IO Word64
loop !Word64
acc !Int
i
        | Int
i forall a. Eq a => a -> a -> Bool
== Int
n = forall (m :: * -> *) a. Monad m => a -> m a
return Word64
acc
        | Bool
otherwise = do
            !Word8
x <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff @Word8 Ptr Word8
ptr Int
i
            Word64 -> Int -> IO Word64
loop (Word64
fnvPrime64 forall a. Num a => a -> a -> a
* (Word64
acc forall a. Bits a => a -> a -> a
`xor` forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
x)) (Int
i forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE fnv1a_64_ #-}

-- -------------------------------------------------------------------------- --
-- FNV1 32 bit

fnv1_32 :: Ptr Word8 -> Int -> IO Word32
fnv1_32 :: Ptr Word8 -> Int -> IO Word32
fnv1_32 !Ptr Word8
ptr !Int
n = Ptr Word8 -> Int -> Word32 -> IO Word32
fnv1_32_ Ptr Word8
ptr Int
n Word32
fnvOffsetBasis32
{-# INLINE fnv1_32 #-}

fnv1_32_ :: Ptr Word8 -> Int -> Word32 -> IO Word32
fnv1_32_ :: Ptr Word8 -> Int -> Word32 -> IO Word32
fnv1_32_ !Ptr Word8
ptr !Int
n !Word32
a = Word32 -> Int -> IO Word32
loop Word32
a Int
0
  where
    loop :: Word32 -> Int -> IO Word32
loop !Word32
acc !Int
i
        | Int
i forall a. Eq a => a -> a -> Bool
== Int
n = forall (m :: * -> *) a. Monad m => a -> m a
return Word32
acc
        | Bool
otherwise = do
            !Word8
x <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff @Word8 Ptr Word8
ptr Int
i
            Word32 -> Int -> IO Word32
loop ((Word32
fnvPrime32 forall a. Num a => a -> a -> a
* Word32
acc) forall a. Bits a => a -> a -> a
`xor` forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
x) (Int
i forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE fnv1_32_ #-}

-- FNV1a 32 bit

fnv1a_32 :: Ptr Word8 -> Int -> IO Word32
fnv1a_32 :: Ptr Word8 -> Int -> IO Word32
fnv1a_32 !Ptr Word8
ptr !Int
n = Ptr Word8 -> Int -> Word32 -> IO Word32
fnv1a_32_ Ptr Word8
ptr Int
n Word32
fnvOffsetBasis32
{-# INLINE fnv1a_32 #-}

fnv1a_32_ :: Ptr Word8 -> Int -> Word32 -> IO Word32
fnv1a_32_ :: Ptr Word8 -> Int -> Word32 -> IO Word32
fnv1a_32_ !Ptr Word8
ptr !Int
n Word32
a = Word32 -> Int -> IO Word32
loop Word32
a Int
0
  where
    loop :: Word32 -> Int -> IO Word32
loop !Word32
acc !Int
i
        | Int
i forall a. Eq a => a -> a -> Bool
== Int
n = forall (m :: * -> *) a. Monad m => a -> m a
return Word32
acc
        | Bool
otherwise = do
            !Word8
x <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff @Word8 Ptr Word8
ptr Int
i
            Word32 -> Int -> IO Word32
loop (Word32
fnvPrime32 forall a. Num a => a -> a -> a
* (Word32
acc forall a. Bits a => a -> a -> a
`xor` forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
x)) (Int
i forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE fnv1a_32_ #-}

-- -------------------------------------------------------------------------- --
-- Host architecture words

-- FNV1

fnv1_host :: Ptr Word8 -> Int -> IO Word
fnv1_host :: Ptr Word8 -> Int -> IO Word
fnv1_host (Ptr Addr#
addr) (I# Int#
n) = forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case forall tok. Addr# -> Int# -> State# tok -> (# State# tok, Word# #)
fnv1Primitive Addr#
addr Int#
n State# RealWorld
s of
    (# State# RealWorld
s1, Word#
w #) -> (# State# RealWorld
s1, Word# -> Word
W# Word#
w #)
{-# INlINE fnv1_host #-}

fnv1_host_ :: Ptr Word8 -> Int -> Word -> IO Word
fnv1_host_ :: Ptr Word8 -> Int -> Word -> IO Word
fnv1_host_ (Ptr Addr#
addr) (I# Int#
n) (W# Word#
a) = forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case forall tok.
Addr# -> Int# -> Word# -> State# tok -> (# State# tok, Word# #)
fnv1Primitive_ Addr#
addr Int#
n Word#
a State# RealWorld
s of
    (# State# RealWorld
s1, Word#
w #) -> (# State# RealWorld
s1, Word# -> Word
W# Word#
w #)
{-# INlINE fnv1_host_ #-}

fnv1Primitive :: Addr# -> Int# -> State# tok -> (# State# tok, Word# #)
fnv1Primitive :: forall tok. Addr# -> Int# -> State# tok -> (# State# tok, Word# #)
fnv1Primitive !Addr#
addr !Int#
n !State# tok
tok = forall tok.
Addr# -> Int# -> Word# -> State# tok -> (# State# tok, Word# #)
fnv1Primitive_ Addr#
addr Int#
n Word#
o State# tok
tok
  where
    !(W# Word#
o) = Word
fnvOffsetBasis
{-# INLINE fnv1Primitive #-}

fnv1Primitive_ :: Addr# -> Int# -> Word# -> State# tok -> (# State# tok, Word# #)
fnv1Primitive_ :: forall tok.
Addr# -> Int# -> Word# -> State# tok -> (# State# tok, Word# #)
fnv1Primitive_ !Addr#
addr !Int#
n !Word#
a State# tok
tok = case Word# -> Int# -> State# tok -> (# State# tok, Word# #)
loop Word#
a Int#
0# State# tok
tok of
    (# State# tok
tok1, Word#
w #) -> (# State# tok
tok1, Word#
w #)
  where
    loop :: Word# -> Int# -> State# tok -> (# State# tok, Word# #)
loop !Word#
acc !Int#
i !State# tok
s = case Int#
i Int# -> Int# -> Int#
==# Int#
n of
        Int#
1# -> (# State# tok
s, Word#
acc #)
        Int#
_ -> case forall d. Addr# -> Int# -> State# d -> (# State# d, Word8# #)
readWord8OffAddr# Addr#
addr Int#
i State# tok
s of
            (# State# tok
s1, Word8#
w #) -> Word# -> Int# -> State# tok -> (# State# tok, Word# #)
loop
                ((Word#
p Word# -> Word# -> Word#
`timesWord#` Word#
acc) Word# -> Word# -> Word#
`xor#` Word8# -> Word#
word8ToWord# Word8#
w)
                (Int#
i Int# -> Int# -> Int#
+# Int#
1#)
                State# tok
s1

    !(W# Word#
p) = Word
fnvPrime
{-# INLINE fnv1Primitive_ #-}

-- -------------------------------------------------------------------------- --
-- Host Wordsize FNV1a

fnv1a_host :: Ptr Word8 -> Int -> IO Word
fnv1a_host :: Ptr Word8 -> Int -> IO Word
fnv1a_host (Ptr Addr#
addr) (I# Int#
n) = forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case forall tok. Addr# -> Int# -> State# tok -> (# State# tok, Word# #)
fnv1aPrimitive Addr#
addr Int#
n State# RealWorld
s of
    (# State# RealWorld
s1, Word#
w #) -> (# State# RealWorld
s1, Word# -> Word
W# Word#
w #)
{-# INlINE fnv1a_host #-}

fnv1a_host_ :: Ptr Word8 -> Int -> Word -> IO Word
fnv1a_host_ :: Ptr Word8 -> Int -> Word -> IO Word
fnv1a_host_ (Ptr Addr#
addr) (I# Int#
n) (W# Word#
a) = forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case forall tok.
Addr# -> Int# -> Word# -> State# tok -> (# State# tok, Word# #)
fnv1aPrimitive_ Addr#
addr Int#
n Word#
a State# RealWorld
s of
    (# State# RealWorld
s1, Word#
w #) -> (# State# RealWorld
s1, Word# -> Word
W# Word#
w #)
{-# INlINE fnv1a_host_ #-}

fnv1aPrimitive :: Addr# -> Int# -> State# tok -> (# State# tok, Word# #)
fnv1aPrimitive :: forall tok. Addr# -> Int# -> State# tok -> (# State# tok, Word# #)
fnv1aPrimitive !Addr#
addr !Int#
n !State# tok
tok = forall tok.
Addr# -> Int# -> Word# -> State# tok -> (# State# tok, Word# #)
fnv1aPrimitive_ Addr#
addr Int#
n Word#
o State# tok
tok
  where
    !(W# Word#
o) = Word
fnvOffsetBasis
{-# INLINE fnv1aPrimitive #-}

fnv1aPrimitive_ :: Addr# -> Int# -> Word# -> State# tok -> (# State# tok, Word# #)
fnv1aPrimitive_ :: forall tok.
Addr# -> Int# -> Word# -> State# tok -> (# State# tok, Word# #)
fnv1aPrimitive_ !Addr#
addr !Int#
n !Word#
a State# tok
tok = case Word# -> Int# -> State# tok -> (# State# tok, Word# #)
loop Word#
a Int#
0# State# tok
tok of
    (# State# tok
tok1, Word#
w #) -> (# State# tok
tok1, Word#
w #)
  where
    loop :: Word# -> Int# -> State# tok -> (# State# tok, Word# #)
loop !Word#
acc !Int#
i !State# tok
s = case Int#
i Int# -> Int# -> Int#
==# Int#
n of
        Int#
1# -> (# State# tok
s, Word#
acc #)
        Int#
_ -> case forall d. Addr# -> Int# -> State# d -> (# State# d, Word8# #)
readWord8OffAddr# Addr#
addr Int#
i State# tok
s of
            (# State# tok
s1, Word8#
w #) ->
                let !acc' :: Word#
acc' = Word#
p Word# -> Word# -> Word#
`timesWord#` (Word#
acc Word# -> Word# -> Word#
`xor#` Word8# -> Word#
word8ToWord# Word8#
w)
                    !n' :: Int#
n' = Int#
i Int# -> Int# -> Int#
+# Int#
1#
                in Word# -> Int# -> State# tok -> (# State# tok, Word# #)
loop Word#
acc' Int#
n' State# tok
s1

    !(W# Word#
p) = Word
fnvPrime
{-# INLINE fnv1aPrimitive_ #-}

-- -------------------------------------------------------------------------- --
-- Backward compatibility

#if !MIN_VERSION_base(4,16,0)
-- | 'readWord8OffAddr#' returns 'Word#' for base < 4.16.0. So, there's no
-- need to convert it to 'Word#' down the road.
--
word8ToWord# :: Word# -> Word#
word8ToWord# a = a
{-# INLINE word8ToWord# #-}
#endif