packages feed

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 #-}