@@ -0,0 +1,66 @@
1+{-# LANGUAGE BangPatterns #-}
3+{-# LANGUAGE ExistentialQuantification #-}
4+{-# LANGUAGE FlexibleContexts #-}
5+{-# LANGUAGE RankNTypes #-}
6+{-# LANGUAGE RecordWildCards #-}
7+{-# LANGUAGE ScopedTypeVariables #-}
10+-- Module : Streamly.Fold.Internal
11+-- Copyright : (c) 2019 Composewell Technologies
12+-- (c) 2013 Gabriel Gonzalez
14+-- Maintainer : harendra.kumar@gmail.com
15+-- Stability : experimental
18+module Streamly.Fold.Internal
21+ , rollingHashWithSalt
22+ -- , rollingHashFirstN
23+ -- , rollingHashLastN
27+import Streamly.Fold.Types (Fold(..))
29+-- | Compute an 'Int' sized polynomial rolling hash
31+-- > H = salt * k ^ n + c1 * k ^ (n - 1) + c2 * k ^ (n - 2) + ... + cn * k ^ 0
33+-- Where @c1@, @c2@, @cn@ are the elements in the input stream and @k@ is a
36+-- This hash is often used in Rabin-Karp string search algorithm.
38+-- See https://en.wikipedia.org/wiki/Rolling_hash
41+{-# INLINABLE rollingHashWithSalt #-}
42+rollingHashWithSalt :: (Monad m, Enum a) => Int -> Fold m a Int
43+rollingHashWithSalt salt = Fold step initial extract
46+ initial = return salt
47+ step cksum a = return $ cksum * k + fromEnum a
50+-- | A default salt used in the implementation of 'rollingHash'.
51+{-# INLINE defaultSalt #-}
53+#if WORD_SIZE_IN_BITS == 64
54+defaultSalt = 0xdc36d1615b7400a4
56+defaultSalt = 0x087fc72c
59+-- | Compute an 'Int' sized polynomial rolling hash of a stream.
61+-- > rollingHash = rollingHashWithSalt defaultSalt
64+{-# INLINABLE rollingHash #-}
65+rollingHash :: (Monad m, Enum a) => Fold m a Int
66+rollingHash = rollingHashWithSalt defaultSalt