packages feed

hw-simd-cli-0.0.0.1: src/HaskellWorks/Simd/Cli/Comparison.hs

{-# LANGUAGE FlexibleInstances #-}

module HaskellWorks.Simd.Cli.Comparison
  ( CmpEqWord8s(..)
  ) where

import Data.ByteString                as BS
import Data.Word
import HaskellWorks.Data.AtIndex
import HaskellWorks.Data.Bits.BitWise
import HaskellWorks.Data.Positioning

import qualified Data.ByteString.Lazy         as LBS
import qualified Data.Vector.Storable         as DVS
import qualified HaskellWorks.Data.ByteString as BS
import qualified HaskellWorks.Data.Length     as HW

class CmpEqWord8s a where
  cmpEqWord8s :: Word8 -> a -> a

instance CmpEqWord8s BS.ByteString where
  cmpEqWord8s w8 bs = BS.toByteString $ DVS.constructN ((BS.length bs + 7) `div` 8) (go 0 0)
    where go :: Word8 -> Count -> DVS.Vector Word8 -> Word8
          go w n u = case HW.length u of
            ui -> case ui * 8 of
              bsi -> if bsi + 8 <= HW.length bs
                then goFast w n u
                else goSafe w n u
          goFast :: Word8 -> Count -> DVS.Vector Word8 -> Word8
          goFast w n u = if n < 8
            then case HW.length u of
              ui -> case ui * 8 of
                bsi -> case bsi + n of
                  wi -> if w8 == bs !!! fromIntegral wi
                    then goFast (w .|. (1 .<. n)) (n + 1) u
                    else goFast  w                (n + 1) u
            else w
          goSafe :: Word8 -> Count -> DVS.Vector Word8 -> Word8
          goSafe w n u = if n < 8
            then case HW.length u of
              ui -> case ui * 8 of
                bsi -> case bsi + n of
                  wi -> if wi < bsLen
                    then if w8 == bs !!! fromIntegral wi
                      then goSafe (w .|. (1 .<. n)) (n + 1) u
                      else goSafe  w                (n + 1) u
                    else w
            else w
          bsLen = HW.length bs
  {-# INLINE cmpEqWord8s #-}

instance CmpEqWord8s [BS.ByteString] where
  cmpEqWord8s w8 vs = cmpEqWord8s w8 <$> vs
  {-# INLINE cmpEqWord8s #-}

instance CmpEqWord8s LBS.ByteString where
  cmpEqWord8s w8 = LBS.fromChunks . cmpEqWord8s w8 . LBS.toChunks
  {-# INLINE cmpEqWord8s #-}