packages feed

lsm-tree-1.0.0.0: src-core/Database/LSMTree/Internal/Page.hs

{-# OPTIONS_HADDOCK not-home #-}

-- | Utilities related to pages.
--
module Database.LSMTree.Internal.Page (
    PageNo (..)
  , nextPageNo
  , NumPages (..)
  , getNumPages
  , PageSpan (..)
  , singlePage
  , multiPage
  , pageSpanSize
  ) where

import           Control.DeepSeq (NFData (..))

-- | A 0-based number identifying a disk page.
newtype PageNo = PageNo { unPageNo :: Int }
  deriving stock (Show, Eq, Ord)
  deriving newtype NFData

-- | Increment the page number.
--
-- Note: This does not ensure that the incremented page number exists within a given page span.
{-# INLINE nextPageNo #-}
nextPageNo :: PageNo -> PageNo
nextPageNo = PageNo . succ . unPageNo

-- | The number of pages contained by an index or other paging data-structure.
--
-- Note: This is a 0-based number; take care to ensure arithmetic underflow
-- does not occur during subtraction operations!
newtype NumPages = NumPages Word
  deriving stock (Eq, Ord, Show)
  deriving newtype (NFData)

-- | A type-safe "unwrapper" for 'NumPages'. Use this accessor whenever you want
-- to convert 'NumPages' to a more versatile number type.
{-# INLINE getNumPages #-}
getNumPages :: Integral i => NumPages -> i
getNumPages (NumPages w) = fromIntegral w

-- | A span of pages, representing an inclusive interval of page numbers.
--
-- Typlically used to denote the contiguous page span for a database entry.
data PageSpan = PageSpan {
    pageSpanStart :: {-# UNPACK #-} !PageNo
  , pageSpanEnd   :: {-# UNPACK #-} !PageNo
  }
  deriving stock (Show, Eq)

instance NFData PageSpan where
  rnf (PageSpan x y) = rnf x `seq` rnf y

{-# INLINE singlePage #-}
singlePage :: PageNo -> PageSpan
singlePage i = PageSpan i i

{-# INLINE multiPage #-}
multiPage :: PageNo -> PageNo -> PageSpan
multiPage i j = PageSpan i j

{-# INLINE pageSpanSize #-}
pageSpanSize :: PageSpan -> NumPages
pageSpanSize pspan = NumPages . toEnum $
    unPageNo (pageSpanEnd pspan) - unPageNo (pageSpanStart pspan) + 1