Add rollingHashLastN combinator

This commit is contained in:
adithyaov 2019-12-06 12:10:32 +05:30
parent 42f1091826
commit 82c6343288

View File

@ -57,7 +57,7 @@ module Streamly.Internal.Data.Fold
, rollingHash
, rollingHashWithSalt
-- , rollingHashFirstN
-- , rollingHashLastN
, rollingHashLastN
-- ** Full Folds (Monoidal)
, mconcat
@ -211,6 +211,9 @@ import Streamly.Internal.Data.Strict
import Streamly.Internal.Data.SVar
import qualified Streamly.Internal.Data.Pipe.Types as Pipe
import qualified Streamly.Memory.Ring as RB
import Foreign.Storable (Storable(..))
------------------------------------------------------------------------------
-- Smart constructors
@ -563,6 +566,29 @@ defaultSalt = 0x087fc72c
rollingHash :: (Monad m, Enum a) => Fold m a Int
rollingHash = rollingHashWithSalt defaultSalt
{-# INLINABLE rollingHashLastN #-}
rollingHashLastN :: (MonadIO m, Enum a) => Int -> Fold m a Int
rollingHashLastN n = Fold step initial extract
where
k = 2891336453
k' = k ^ n
initial = do
(rb, rh) <- liftIO $ RB.new n
return (defaultSalt, rb, rh, 0, 0)
step (dSA, rb, rh, i, cksum) a
| i < n = do
let ea = fromEnum a
rh1 <- liftIO $ RB.unsafeInsert rb rh ea
return (dSA * k, rb, rh1, i + 1, cksum * k + ea)
| otherwise = do
let ea = fromEnum a
a' <- liftIO $ peek rh
rh1 <- liftIO $ RB.unsafeInsert rb rh ea
-- XXX You don't need to change i to i + 1 here
-- XXX Can remove this additional operation
return (dSA, rb, rh1, i + 1, cksum * k - a' * k' + ea)
extract (dSA, _, _, _, cksum) = return $ dSA + cksum
------------------------------------------------------------------------------
-- Monoidal left folds
------------------------------------------------------------------------------