hask-redis-mux-0.1.0.0: lib/crc16/Database/Redis/Crc16.hs
-- | CRC16 hash computation for Redis cluster slot assignment.
-- Wraps a C implementation via FFI. The FFI call is safe to treat as pure
-- (deterministic, no side effects), so we use 'unsafeDupablePerformIO' to
-- avoid forcing callers into IO on the hot path.
--
-- @since 0.1.0.0
module Database.Redis.Crc16 ( crc16 ) where
import Data.Bits ((.&.))
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BS8
import Data.Word (Word16)
import Foreign.C.String (CString)
import Foreign.C.Types (CInt (..), CUShort (..))
import System.IO.Unsafe (unsafeDupablePerformIO)
-- Foreign function interface to the C function (marked unsafe for speed — no callbacks)
foreign import ccall unsafe "crc16" c_crc16 :: CString -> CInt -> CUShort
-- | Compute the CRC16 hash of a key, reduced to the Redis cluster slot range (0–16383).
-- Pure: the underlying C function is deterministic with no side effects.
crc16 :: ByteString -> Word16
crc16 bs = unsafeDupablePerformIO $
BS8.useAsCStringLen bs $ \(cstr, len) -> do
let !result = c_crc16 cstr (fromIntegral len)
return $! fromIntegral result .&. (0x3FFF :: Word16)
{-# INLINE crc16 #-}