Skip to content

Commit

Permalink
Move functions from Data.Serialize to Data.Internal.Serialize
Browse files Browse the repository at this point in the history
  • Loading branch information
adithyaov committed Aug 18, 2023
1 parent c4343a4 commit 9be03c8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 54 deletions.
62 changes: 10 additions & 52 deletions core/src/Streamly/Data/Serialize.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,65 +30,23 @@ module Streamly.Data.Serialize
, decode
) where

#include "assert.hs"
--------------------------------------------------------------------------------
-- Imports
--------------------------------------------------------------------------------

import Data.Int (Int64)
import Data.Word (Word8)
import Streamly.Internal.Data.Array.Type (Array(..))
import Streamly.Internal.Data.Serialize (Serialize(..), Size(..))
import Streamly.Internal.Data.Serialize
( Serialize(..)
, Size(..)
, decode
, encode
, pinnedEncode
)
import Streamly.Internal.Data.Serialize.TH
( deriveSerialize
, deriveSerializeWith
)
import Streamly.Internal.Data.Unbox
( MutableByteArray
, PinnedState(..)
, Unbox(..)
)
import Streamly.Internal.Data.Unbox.TH (deriveUnbox, deriveUnboxWith)
import Streamly.Internal.System.IO (unsafeInlineIO)

import qualified Streamly.Internal.Data.Unbox as Unbox
import qualified Streamly.Internal.Data.Array as Array

--------------------------------------------------------------------------------
-- Serialize
--------------------------------------------------------------------------------

{-# INLINE encodeAs #-}
encodeAs :: forall a. Serialize a => PinnedState -> a -> Array Word8
encodeAs ps a =
unsafeInlineIO $ do
let len =
case size :: Size a of
ConstSize sz -> sz
VarSize f -> f a
-- We encode the length of the encoding as a header hence the 8 extra
-- bytes to encode Int64
mbarr <- Unbox.newBytesAs ps (8 + len)
off1 <- serialize 0 mbarr (fromIntegral len :: Int64)
off2 <- serialize off1 mbarr a
assertM(off2 == len + off1)
pure $ Array mbarr 0 len

{-# INLINE encode #-}
encode :: Serialize a => a -> Array Word8
encode = encodeAs Unpinned

{-# INLINE pinnedEncode #-}
pinnedEncode :: Serialize a => a -> Array Word8
pinnedEncode = encodeAs Pinned

--------------------------------------------------------------------------------
-- Deserialize
--------------------------------------------------------------------------------

{-# INLINE decode #-}
decode :: Serialize a => Array Word8 -> a
decode arr@(Array {..}) = unsafeInlineIO $ do
let lenArr = Array.length arr
(off1, lenEncoding :: Int64) <- deserialize 0 arrContents
(off2, val) <- deserialize off1 arrContents
assertM(fromIntegral lenEncoding + off1 == off2)
assertM(lenArr == off2)
pure val
49 changes: 47 additions & 2 deletions core/src/Streamly/Internal/Data/Serialize.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,29 @@
module Streamly.Internal.Data.Serialize
( Size(..)
, Serialize(..)
, encode
, pinnedEncode
, decode
) where

--------------------------------------------------------------------------------
-- Imports
--------------------------------------------------------------------------------

#include "assert.hs"

import Control.Monad (void)
import Data.List (foldl')
import Data.Proxy (Proxy (..))
import Streamly.Internal.Data.Unbox (MutableByteArray(..))

import Streamly.Internal.Data.Unbox (MutableByteArray(..), PinnedState(..))
import Streamly.Internal.Data.Array.Type (Array(..))
import Streamly.Internal.System.IO (unsafeInlineIO)
import GHC.Int (Int16(..), Int32(..), Int64(..), Int8(..))
import GHC.Word (Word16(..), Word32(..), Word64(..), Word8(..))
import GHC.Stable (StablePtr(..))

import qualified Streamly.Internal.Data.Unbox as Unbox
import qualified Streamly.Internal.Data.Array as Array

import GHC.Exts

Expand Down Expand Up @@ -167,3 +174,41 @@ instance forall a. Serialize a => Serialize [a] where
o1 <- serialize o arr x
pokeList o1 xs
pokeList off1 val

--------------------------------------------------------------------------------
-- High level functions
--------------------------------------------------------------------------------

{-# INLINE encodeAs #-}
encodeAs :: forall a. Serialize a => PinnedState -> a -> Array Word8
encodeAs ps a =
unsafeInlineIO $ do
let len =
case size :: Size a of
ConstSize sz -> sz
VarSize f -> f a
-- We encode the length of the encoding as a header hence the 8 extra
-- bytes to encode Int64
mbarr <- Unbox.newBytesAs ps (8 + len)
off1 <- serialize 0 mbarr (fromIntegral len :: Int64)
off2 <- serialize off1 mbarr a
assertM(off2 == len + off1)
pure $ Array mbarr 0 len

{-# INLINE encode #-}
encode :: Serialize a => a -> Array Word8
encode = encodeAs Unpinned

{-# INLINE pinnedEncode #-}
pinnedEncode :: Serialize a => a -> Array Word8
pinnedEncode = encodeAs Pinned

{-# INLINE decode #-}
decode :: Serialize a => Array Word8 -> a
decode arr@(Array {..}) = unsafeInlineIO $ do
let lenArr = Array.length arr
(off1, lenEncoding :: Int64) <- deserialize 0 arrContents
(off2, val) <- deserialize off1 arrContents
assertM(fromIntegral lenEncoding + off1 == off2)
assertM(lenArr == off2)
pure val

0 comments on commit 9be03c8

Please sign in to comment.