{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Data.Cuckoo.Internal
( w
, int
, fit
, intFit
, nextPowerOfTwo
, intNextPowerOfTwo
, set
, get
) where
import Control.Monad.Primitive
import Data.Bits
import Data.Primitive.ByteArray
import Foreign
import GHC.Exts
import GHC.TypeLits
w :: forall (n :: Nat) . KnownNat n => Int
w :: Int
w = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
int (Integer -> Int) -> Integer -> Int
forall a b. (a -> b) -> a -> b
$ Proxy# n -> Integer
forall (n :: Nat). KnownNat n => Proxy# n -> Integer
natVal' @n Proxy# n
forall k (a :: k). Proxy# a
proxy#
{-# INLINE w #-}
int :: Integral a => Num b => a -> b
int :: a -> b
int = a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE int #-}
fit :: Real a => Real b => Integral c => a -> b -> c
fit :: a -> b -> c
fit a
a b
b = forall b. (RealFrac Double, Integral b) => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling @Double (Double -> c) -> Double -> c
forall a b. (a -> b) -> a -> b
$ a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
a Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ b -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac b
b
{-# INLINE fit #-}
intFit :: Integral a => Integral b => a -> b -> a
intFit :: a -> b -> a
intFit a
a b
b = a
1 a -> a -> a
forall a. Num a => a -> a -> a
+ (a
a a -> a -> a
forall a. Num a => a -> a -> a
- a
1) a -> a -> a
forall a. Integral a => a -> a -> a
`div` b -> a
forall a b. (Integral a, Num b) => a -> b
int b
b
{-# INLINE intFit #-}
nextPowerOfTwo :: Real a => Integral b => a -> b
nextPowerOfTwo :: a -> b
nextPowerOfTwo a
x = b
2 b -> Int -> b
forall a b. (Num a, Integral b) => a -> b -> a
^ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling @Double @Int (Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase Double
2 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
x)
{-# INLINE nextPowerOfTwo #-}
intNextPowerOfTwo :: Int -> Int
intNextPowerOfTwo :: Int -> Int
intNextPowerOfTwo Int
0 = Int
1
intNextPowerOfTwo Int
x = Int
1 Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`unsafeShiftL` (Int -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int -> Int
forall b. FiniteBits b => b -> Int
countLeadingZeros (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
{-# INLINE intNextPowerOfTwo #-}
set
:: PrimMonad m
=> MutableByteArray (PrimState m)
-> Int
-> Word64
-> m ()
set :: MutableByteArray (PrimState m) -> Int -> Word64 -> m ()
set MutableByteArray (PrimState m)
x Int
i Word64
c = do
MutableByteArray (PrimState m) -> Int -> Word32 -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray @Word32 MutableByteArray (PrimState m)
x Int
i (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
int Word64
c)
MutableByteArray (PrimState m) -> Int -> Word32 -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray @Word32 MutableByteArray (PrimState m)
x (Int -> Int
forall a. Enum a => a -> a
succ Int
i) (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
int (Word64 -> Word32) -> Word64 -> Word32
forall a b. (a -> b) -> a -> b
$ Word64
c Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
32)
{-# INLINE set #-}
get
:: PrimMonad m
=> MutableByteArray (PrimState m)
-> Int
-> m Word64
get :: MutableByteArray (PrimState m) -> Int -> m Word64
get MutableByteArray (PrimState m)
x Int
i = do
Word32
a <- MutableByteArray (PrimState m) -> Int -> m Word32
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
readByteArray @Word32 MutableByteArray (PrimState m)
x Int
i
Word32
b <- MutableByteArray (PrimState m) -> Int -> m Word32
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
readByteArray @Word32 MutableByteArray (PrimState m)
x (Int -> Int
forall a. Enum a => a -> a
succ Int
i)
Word64 -> m Word64
forall (m :: * -> *) a. Monad m => a -> m a
return (Word64 -> m Word64) -> Word64 -> m Word64
forall a b. (a -> b) -> a -> b
$! Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
int Word32
a Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ (Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
int Word32
b Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
32)
{-# INLINE get #-}