lsm-tree-1.0.0.0: src-core/Database/LSMTree/Internal/BitMath.hs
{-# OPTIONS_HADDOCK not-home #-}
-- | Some arithmetic implemented using bit operations
--
-- Valid for non-negative arguments.
module Database.LSMTree.Internal.BitMath (
-- * Two
div2,
mod2,
mul2,
ceilDiv2,
-- * Four
div4,
mod4,
mul4,
-- * Eight
div8,
mod8,
mul8,
ceilDiv8,
-- * Sixteen
div16,
mod16,
mul16,
-- * 32
div32,
mod32,
-- * 64
div64,
mod64,
mul64,
ceilDiv64,
-- * 4096, page size
divPageSize,
modPageSize,
mulPageSize,
ceilDivPageSize,
roundUpToPageSize,
) where
import Data.Bits
-------------------------------------------------------------------------------
-- 2
-------------------------------------------------------------------------------
div2 :: Bits a => a -> a
div2 x = unsafeShiftR x 1
{-# INLINE div2 #-}
mod2 :: (Bits a, Num a) => a -> a
mod2 x = x .&. 1
{-# INLINE mod2 #-}
mul2 :: Bits a => a -> a
mul2 x = unsafeShiftL x 1
{-# INLINE mul2 #-}
ceilDiv2 :: (Bits a, Num a) => a -> a
ceilDiv2 i = unsafeShiftR (i + 1) 1
{-# INLINE ceilDiv2 #-}
-------------------------------------------------------------------------------
-- 4
-------------------------------------------------------------------------------
div4 :: Bits a => a -> a
div4 x = unsafeShiftR x 2
{-# INLINE div4 #-}
mod4 :: (Bits a, Num a) => a -> a
mod4 x = x .&. 3
{-# INLINE mod4 #-}
mul4 :: Bits a => a -> a
mul4 x = unsafeShiftL x 2
{-# INLINE mul4 #-}
-------------------------------------------------------------------------------
-- 8
-------------------------------------------------------------------------------
div8 :: Bits a => a -> a
div8 x = unsafeShiftR x 3
{-# INLINE div8 #-}
mod8 :: (Bits a, Num a) => a -> a
mod8 x = x .&. 7
{-# INLINE mod8 #-}
mul8 :: Bits a => a -> a
mul8 x = unsafeShiftL x 3
{-# INLINE mul8 #-}
ceilDiv8 :: (Bits a, Num a) => a -> a
ceilDiv8 i = unsafeShiftR (i + 7) 3
{-# INLINE ceilDiv8 #-}
-------------------------------------------------------------------------------
-- 16
-------------------------------------------------------------------------------
div16 :: Bits a => a -> a
div16 x = unsafeShiftR x 4
{-# INLINE div16 #-}
mod16 :: (Bits a, Num a) => a -> a
mod16 x = x .&. 15
{-# INLINE mod16 #-}
mul16 :: Bits a => a -> a
mul16 x = unsafeShiftL x 4
{-# INLINE mul16 #-}
-------------------------------------------------------------------------------
-- 32
-------------------------------------------------------------------------------
div32 :: Bits a => a -> a
div32 x = unsafeShiftR x 5
{-# INLINE div32 #-}
mod32 :: (Bits a, Num a) => a -> a
mod32 x = x .&. 31
{-# INLINE mod32 #-}
-------------------------------------------------------------------------------
-- 64
-------------------------------------------------------------------------------
-- |
--
-- >>> map div64 [0 :: Word, 1, 63, 64, 65]
-- [0,0,0,1,1]
--
div64 :: Bits a => a -> a
div64 x = unsafeShiftR x 6
{-# INLINE div64 #-}
-- |
--
-- >>> map mod64 [0 :: Word, 1, 63, 64, 65]
-- [0,1,63,0,1]
--
mod64 :: (Bits a, Num a) => a -> a
mod64 x = x .&. 63
{-# INLINE mod64 #-}
mul64 :: Bits a => a -> a
mul64 x = unsafeShiftL x 6
{-# INLINE mul64 #-}
-- | rounding up division
--
-- >>> map ceilDiv64 [0 :: Word, 1, 63, 64, 65]
-- [0,1,1,1,2]
--
ceilDiv64 :: (Bits a, Num a) => a -> a
ceilDiv64 i = unsafeShiftR (i + 63) 6
{-# INLINE ceilDiv64 #-}
-------------------------------------------------------------------------------
-- 4096
-------------------------------------------------------------------------------
-- | Assumes @pageSize = 4096@.
divPageSize :: Bits a => a -> a
divPageSize x = unsafeShiftR x 12
{-# INLINE divPageSize #-}
-- | Assumes @pageSize = 4096@.
modPageSize :: (Bits a, Num a) => a -> a
modPageSize x = x .&. 4095
{-# INLINE modPageSize #-}
-- | Assumes @pageSize = 4096@.
mulPageSize :: Bits a => a -> a
mulPageSize x = unsafeShiftL x 12
{-# INLINE mulPageSize #-}
-- | Assumes @pageSize = 4096@.
ceilDivPageSize :: (Bits a, Num a) => a -> a
ceilDivPageSize x = unsafeShiftR (x + 4095) 12
{-# INLINE ceilDivPageSize #-}
-- | Assumes @pageSize = 4096@.
roundUpToPageSize :: (Bits a, Num a) => a -> a
roundUpToPageSize x = (x + 4095) .&. complement 4095
{-# INLINE roundUpToPageSize #-}