{-# OPTIONS_HADDOCK not-home #-}
module Database.LSMTree.Internal.Serialise.Class (
SerialiseKey (..)
, serialiseKeyIdentity
, serialiseKeyIdentityUpToSlicing
, serialiseKeyPreservesOrdering
, serialiseKeyMinimalSize
, SerialiseValue (..)
, serialiseValueIdentity
, serialiseValueIdentityUpToSlicing
, RawBytes (..)
, packSlice
, requireBytesExactly
) where
import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Short.Internal as SBS
import Data.Monoid (Sum (..))
import qualified Data.Primitive as P
import qualified Data.Vector.Primitive as VP
import Data.Void (Void, absurd)
import Data.Word
import Database.LSMTree.Internal.ByteString (byteArrayToSBS)
import Database.LSMTree.Internal.Primitive (indexWord8ArrayAsWord64)
import Database.LSMTree.Internal.RawBytes (RawBytes (..))
import qualified Database.LSMTree.Internal.RawBytes as RB
import Database.LSMTree.Internal.Vector
import Numeric (showInt)
class SerialiseKey k where
serialiseKey :: k -> RawBytes
deserialiseKey :: RawBytes -> k
serialiseKeyIdentity :: (Eq k, SerialiseKey k) => k -> Bool
serialiseKeyIdentity :: forall k. (Eq k, SerialiseKey k) => k -> Bool
serialiseKeyIdentity k
x = RawBytes -> k
forall k. SerialiseKey k => RawBytes -> k
deserialiseKey (k -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey k
x) k -> k -> Bool
forall a. Eq a => a -> a -> Bool
== k
x
serialiseKeyIdentityUpToSlicing ::
(Eq k, SerialiseKey k)
=> RawBytes -> k -> RawBytes -> Bool
serialiseKeyIdentityUpToSlicing :: forall k.
(Eq k, SerialiseKey k) =>
RawBytes -> k -> RawBytes -> Bool
serialiseKeyIdentityUpToSlicing RawBytes
prefix k
x RawBytes
suffix =
RawBytes -> k
forall k. SerialiseKey k => RawBytes -> k
deserialiseKey (RawBytes -> RawBytes -> RawBytes -> RawBytes
packSlice RawBytes
prefix (k -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey k
x) RawBytes
suffix) k -> k -> Bool
forall a. Eq a => a -> a -> Bool
== k
x
serialiseKeyPreservesOrdering :: (Ord k, SerialiseKey k) => k -> k -> Bool
serialiseKeyPreservesOrdering :: forall k. (Ord k, SerialiseKey k) => k -> k -> Bool
serialiseKeyPreservesOrdering k
x k
y = k
x k -> k -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` k
y Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== k -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey k
x RawBytes -> RawBytes -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` k -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey k
y
serialiseKeyMinimalSize :: SerialiseKey k => k -> Bool
serialiseKeyMinimalSize :: forall k. SerialiseKey k => k -> Bool
serialiseKeyMinimalSize k
x = RawBytes -> Int
RB.size (k -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey k
x) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
8
class SerialiseValue v where
serialiseValue :: v -> RawBytes
deserialiseValue :: RawBytes -> v
instance SerialiseValue a => SerialiseValue (Sum a) where
serialiseValue :: Sum a -> RawBytes
serialiseValue (Sum a
v) = a -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue a
v
deserialiseValue :: RawBytes -> Sum a
deserialiseValue = a -> Sum a
forall a. a -> Sum a
Sum (a -> Sum a) -> (RawBytes -> a) -> RawBytes -> Sum a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> a
forall v. SerialiseValue v => RawBytes -> v
deserialiseValue
serialiseValueIdentity :: (Eq v, SerialiseValue v) => v -> Bool
serialiseValueIdentity :: forall v. (Eq v, SerialiseValue v) => v -> Bool
serialiseValueIdentity v
x = RawBytes -> v
forall v. SerialiseValue v => RawBytes -> v
deserialiseValue (v -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue v
x) v -> v -> Bool
forall a. Eq a => a -> a -> Bool
== v
x
serialiseValueIdentityUpToSlicing ::
(Eq v, SerialiseValue v)
=> RawBytes -> v -> RawBytes -> Bool
serialiseValueIdentityUpToSlicing :: forall v.
(Eq v, SerialiseValue v) =>
RawBytes -> v -> RawBytes -> Bool
serialiseValueIdentityUpToSlicing RawBytes
prefix v
x RawBytes
suffix =
RawBytes -> v
forall v. SerialiseValue v => RawBytes -> v
deserialiseValue (RawBytes -> RawBytes -> RawBytes -> RawBytes
packSlice RawBytes
prefix (v -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue v
x) RawBytes
suffix) v -> v -> Bool
forall a. Eq a => a -> a -> Bool
== v
x
packSlice :: RawBytes -> RawBytes -> RawBytes -> RawBytes
packSlice :: RawBytes -> RawBytes -> RawBytes -> RawBytes
packSlice RawBytes
prefix RawBytes
x RawBytes
suffix =
Int -> RawBytes -> RawBytes
RB.take (RawBytes -> Int
RB.size RawBytes
x) (Int -> RawBytes -> RawBytes
RB.drop (RawBytes -> Int
RB.size RawBytes
prefix) (RawBytes
prefix RawBytes -> RawBytes -> RawBytes
forall a. Semigroup a => a -> a -> a
<> RawBytes
x RawBytes -> RawBytes -> RawBytes
forall a. Semigroup a => a -> a -> a
<> RawBytes
suffix))
requireBytesExactly :: String -> Int -> Int -> a -> a
requireBytesExactly :: forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
tyName Int
expected Int
actual a
x
| Int
expected Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
actual = a
x
| Bool
otherwise =
String -> a
forall a. HasCallStack => String -> a
error
(String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String -> ShowS
showString String
"deserialise "
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
tyName
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
": expected "
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Integral a => a -> ShowS
showInt Int
expected
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
" bytes, but got "
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Integral a => a -> ShowS
showInt Int
actual
ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String
""
instance SerialiseKey Word64 where
serialiseKey :: Word64 -> RawBytes
serialiseKey Word64
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word64 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word64 -> Vector Word8) -> Word64 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64
byteSwap64 Word64
x
deserialiseKey :: RawBytes -> Word64
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
String -> Int -> Int -> Word64 -> Word64
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word64" Int
8 Int
len (Word64 -> Word64) -> Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64
byteSwap64 (ByteArray -> Int -> Word64
indexWord8ArrayAsWord64 ByteArray
ba Int
off)
instance SerialiseValue Word64 where
serialiseValue :: Word64 -> RawBytes
serialiseValue Word64
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word64 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word64 -> Vector Word8) -> Word64 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word64
x
deserialiseValue :: RawBytes -> Word64
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
String -> Int -> Int -> Word64 -> Word64
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word64" Int
8 Int
len (Word64 -> Word64) -> Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word64
indexWord8ArrayAsWord64 ByteArray
ba Int
off
instance SerialiseKey LBS.ByteString where
serialiseKey :: ByteString -> RawBytes
serialiseKey = ByteString -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey (ByteString -> RawBytes)
-> (ByteString -> ByteString) -> ByteString -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
LBS.toStrict
deserialiseKey :: RawBytes -> ByteString
deserialiseKey = Builder -> ByteString
B.toLazyByteString (Builder -> ByteString)
-> (RawBytes -> Builder) -> RawBytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> Builder
RB.builder
instance SerialiseKey BS.ByteString where
serialiseKey :: ByteString -> RawBytes
serialiseKey = ShortByteString -> RawBytes
RB.fromShortByteString (ShortByteString -> RawBytes)
-> (ByteString -> ShortByteString) -> ByteString -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ShortByteString
SBS.toShort
deserialiseKey :: RawBytes -> ByteString
deserialiseKey = ByteString -> ByteString
LBS.toStrict (ByteString -> ByteString)
-> (RawBytes -> ByteString) -> RawBytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ByteString
forall k. SerialiseKey k => RawBytes -> k
deserialiseKey
instance SerialiseValue LBS.ByteString where
serialiseValue :: ByteString -> RawBytes
serialiseValue = ByteString -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue (ByteString -> RawBytes)
-> (ByteString -> ByteString) -> ByteString -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
LBS.toStrict
deserialiseValue :: RawBytes -> ByteString
deserialiseValue = Builder -> ByteString
B.toLazyByteString (Builder -> ByteString)
-> (RawBytes -> Builder) -> RawBytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> Builder
RB.builder
instance SerialiseValue BS.ByteString where
serialiseValue :: ByteString -> RawBytes
serialiseValue = ShortByteString -> RawBytes
RB.fromShortByteString (ShortByteString -> RawBytes)
-> (ByteString -> ShortByteString) -> ByteString -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ShortByteString
SBS.toShort
deserialiseValue :: RawBytes -> ByteString
deserialiseValue = ByteString -> ByteString
LBS.toStrict (ByteString -> ByteString)
-> (RawBytes -> ByteString) -> RawBytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ByteString
forall v. SerialiseValue v => RawBytes -> v
deserialiseValue
instance SerialiseKey SBS.ShortByteString where
serialiseKey :: ShortByteString -> RawBytes
serialiseKey = ShortByteString -> RawBytes
RB.fromShortByteString
deserialiseKey :: RawBytes -> ShortByteString
deserialiseKey = ByteArray -> ShortByteString
byteArrayToSBS (ByteArray -> ShortByteString)
-> (RawBytes -> ByteArray) -> RawBytes -> ShortByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ByteArray
RB.force
instance SerialiseValue SBS.ShortByteString where
serialiseValue :: ShortByteString -> RawBytes
serialiseValue = ShortByteString -> RawBytes
RB.fromShortByteString
deserialiseValue :: RawBytes -> ShortByteString
deserialiseValue = ByteArray -> ShortByteString
byteArrayToSBS (ByteArray -> ShortByteString)
-> (RawBytes -> ByteArray) -> RawBytes -> ShortByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ByteArray
RB.force
instance SerialiseValue P.ByteArray where
serialiseValue :: ByteArray -> RawBytes
serialiseValue ByteArray
ba = Int -> Int -> ByteArray -> RawBytes
RB.fromByteArray Int
0 (ByteArray -> Int
P.sizeofByteArray ByteArray
ba) ByteArray
ba
deserialiseValue :: RawBytes -> ByteArray
deserialiseValue = RawBytes -> ByteArray
RB.force
instance SerialiseValue Void where
serialiseValue :: Void -> RawBytes
serialiseValue = Void -> RawBytes
forall a. Void -> a
absurd
deserialiseValue :: RawBytes -> Void
deserialiseValue = String -> RawBytes -> Void
forall a. HasCallStack => String -> a
error String
"panic"