lsm-tree-1.0.0.0: src-core/Database/LSMTree/Internal/PageAcc1.hs
{-# OPTIONS_HADDOCK not-home #-}
-- | Create a single value page
--
module Database.LSMTree.Internal.PageAcc1 (
singletonPage,
) where
import Control.Monad.ST.Strict (ST, runST)
import qualified Data.Primitive as P
import qualified Data.Vector.Primitive as VP
import Data.Word (Word16, Word32, Word64)
import Database.LSMTree.Internal.BlobRef (BlobSpan (..))
import Database.LSMTree.Internal.Entry (Entry (..))
import Database.LSMTree.Internal.RawBytes (RawBytes (..))
import qualified Database.LSMTree.Internal.RawBytes as RB
import Database.LSMTree.Internal.RawOverflowPage
import Database.LSMTree.Internal.RawPage
import Database.LSMTree.Internal.Serialise
pageSize :: Int
pageSize = 4096
{-# INLINE pageSize #-}
-- | Create a singleton page, also returning the overflow value bytes.
singletonPage ::
SerialisedKey
-> Entry SerialisedValue BlobSpan
-> (RawPage, [RawOverflowPage])
singletonPage k (Insert v) = runST $ do
-- allocate bytearray
ba <- P.newPinnedByteArray pageSize :: ST s (P.MutableByteArray s)
P.fillByteArray ba 0 pageSize 0
-- directory: 64 bytes
P.writeByteArray ba 0 (1 :: Word16)
P.writeByteArray ba 1 (0 :: Word16)
P.writeByteArray ba 2 (24 :: Word16)
-- blobref and operation bitmap sizes in bytes
-- P.writeByteArray ba 1 (0 :: Word64)
-- P.writeByteArray ba 2 (0 :: Word64)
-- no blob references
P.writeByteArray ba 12 (32 :: Word16) -- key offset
P.writeByteArray ba 13 (32 + sizeofKey16 k :: Word16) -- value offset
P.writeByteArray ba 7 (32 + sizeofKey32 k + sizeofValue32 v :: Word32) -- post value offset
-- copy key
P.copyByteArray ba 32 kba koff klen
-- copy value prefix
let vlen' = min vlen (pageSize - klen - 32)
P.copyByteArray ba (32 + klen) vba voff vlen'
ba' <- P.unsafeFreezeByteArray ba
let !page = unsafeMakeRawPage ba' 0
!overflowPages = rawBytesToOverflowPages (RB.drop vlen' v')
pure (page, overflowPages)
where
SerialisedKey (RawBytes (VP.Vector koff klen kba)) = k
SerialisedValue v'@(RawBytes (VP.Vector voff vlen vba)) = v
singletonPage k (InsertWithBlob v (BlobSpan w64 w32)) = runST $ do
-- allocate bytearray
ba <- P.newPinnedByteArray pageSize :: ST s (P.MutableByteArray s)
P.fillByteArray ba 0 pageSize 0
-- directory: 64 bytes
P.writeByteArray ba 0 (1 :: Word16)
P.writeByteArray ba 1 (1 :: Word16)
P.writeByteArray ba 2 (36 :: Word16)
-- blobref and operation bitmap sizes in bytes
P.writeByteArray ba 1 (1 :: Word64)
-- P.writeByteArray ba 2 (0 :: Word64)
-- blob references
P.writeByteArray ba 3 w64
P.writeByteArray ba 8 w32
P.writeByteArray ba 18 (44 :: Word16) -- key offset
P.writeByteArray ba 19 (44 + sizeofKey16 k :: Word16) -- value offset
P.writeByteArray ba 10 (44 + sizeofKey32 k + sizeofValue32 v :: Word32) -- post value offset
-- copy key
P.copyByteArray ba 44 kba koff klen
-- copy value prefix
let vlen' = min vlen (pageSize - klen - 44)
P.copyByteArray ba (44 + klen) vba voff vlen'
ba' <- P.unsafeFreezeByteArray ba
let !page = unsafeMakeRawPage ba' 0
!overflowPages = rawBytesToOverflowPages (RB.drop vlen' v')
pure (page, overflowPages)
where
SerialisedKey (RawBytes (VP.Vector koff klen kba)) = k
SerialisedValue v'@(RawBytes (VP.Vector voff vlen vba)) = v
singletonPage k (Upsert v) = runST $ do
-- allocate bytearray
ba <- P.newPinnedByteArray pageSize :: ST s (P.MutableByteArray s)
P.fillByteArray ba 0 pageSize 0
-- directory: 64 bytes
P.writeByteArray ba 0 (1 :: Word16)
P.writeByteArray ba 1 (0 :: Word16)
P.writeByteArray ba 2 (24 :: Word16)
-- blobref and operation bitmap sizes in bytes
-- P.writeByteArray ba 1 (0 :: Word64)
P.writeByteArray ba 2 (1 :: Word64)
-- no blob references
P.writeByteArray ba 12 (32 :: Word16) -- key offset
P.writeByteArray ba 13 (32 + sizeofKey16 k :: Word16) -- value offset
P.writeByteArray ba 7 (32 + sizeofKey32 k + sizeofValue32 v :: Word32) -- post value offset
-- copy key
P.copyByteArray ba 32 kba koff klen
-- copy value prefix
let vlen' = min vlen (pageSize - klen - 32)
P.copyByteArray ba (32 + klen) vba voff vlen'
ba' <- P.unsafeFreezeByteArray ba
let !page = unsafeMakeRawPage ba' 0
!overflowPages = rawBytesToOverflowPages (RB.drop vlen' v')
pure (page, overflowPages)
where
SerialisedKey (RawBytes (VP.Vector koff klen kba)) = k
SerialisedValue v'@(RawBytes (VP.Vector voff vlen vba)) = v
singletonPage _ Delete = error "singletonPage: unexpected Delete entry"