module Entry (Entry (..), Checksum, Timestamp, FieldSize, Key, Value, matchChecksum, nanosSinceEpoch, buildEntry, getEntryLength) where import qualified Data.ByteString.Lazy as B import qualified Data.ByteString.Lazy.UTF8 as BU import Data.Digest.CRC32 (crc32) import Data.Int (Int64) import Data.String.Interpolate (i) import Data.Time (nominalDiffTimeToSeconds) import Data.Time.Clock.POSIX (getPOSIXTime) import Data.Word (Word32) type Checksum = Word32 type Timestamp = Int64 type FieldSize = Int64 type Key = B.ByteString type Value = B.ByteString data Entry = Entry Checksum Timestamp FieldSize FieldSize Key Value deriving (Entry -> Entry -> Bool (Entry -> Entry -> Bool) -> (Entry -> Entry -> Bool) -> Eq Entry forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: Entry -> Entry -> Bool == :: Entry -> Entry -> Bool $c/= :: Entry -> Entry -> Bool /= :: Entry -> Entry -> Bool Eq) instance Show Entry where show :: Entry -> String show (Entry Checksum fileid FieldSize timestamp FieldSize ksize FieldSize vsize Key key Key value) = [i|#{fileid'} #{timestamp'} #{ksize'} #{vsize'} #{key'} #{value'}|] where fileid' :: String fileid' = Checksum -> String forall a. Show a => a -> String show Checksum fileid timestamp' :: String timestamp' = FieldSize -> String forall a. Show a => a -> String show FieldSize timestamp ksize' :: String ksize' = FieldSize -> String forall a. Show a => a -> String show FieldSize ksize vsize' :: String vsize' = FieldSize -> String forall a. Show a => a -> String show FieldSize vsize key' :: String key' = Key -> String BU.toString Key key value' :: String value' = Key -> String BU.toString Key value nanosSinceEpoch :: IO Timestamp nanosSinceEpoch :: IO FieldSize nanosSinceEpoch = do POSIXTime t <- IO POSIXTime getPOSIXTime FieldSize -> IO FieldSize forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure (FieldSize -> IO FieldSize) -> FieldSize -> IO FieldSize forall a b. (a -> b) -> a -> b $ Pico -> FieldSize forall b. Integral b => Pico -> b forall a b. (RealFrac a, Integral b) => a -> b floor (Pico -> FieldSize) -> Pico -> FieldSize forall a b. (a -> b) -> a -> b $ Pico 1e9 Pico -> Pico -> Pico forall a. Num a => a -> a -> a * POSIXTime -> Pico nominalDiffTimeToSeconds POSIXTime t buildEntry :: Timestamp -> Key -> Value -> Entry buildEntry :: FieldSize -> Key -> Key -> Entry buildEntry FieldSize timestamp Key key Key value = Checksum -> FieldSize -> FieldSize -> FieldSize -> Key -> Key -> Entry Entry Checksum checksum FieldSize timestamp FieldSize keyl FieldSize valuel Key key Key value where checksum :: Checksum checksum = Key -> Checksum forall a. CRC32 a => a -> Checksum crc32 (Key -> Checksum) -> Key -> Checksum forall a b. (a -> b) -> a -> b $ String -> Key BU.fromString (String -> Key) -> String -> Key forall a b. (a -> b) -> a -> b $ FieldSize -> String forall a. Show a => a -> String show FieldSize timestamp String -> ShowS forall a. [a] -> [a] -> [a] ++ FieldSize -> String forall a. Show a => a -> String show FieldSize keyl String -> ShowS forall a. [a] -> [a] -> [a] ++ FieldSize -> String forall a. Show a => a -> String show FieldSize valuel String -> ShowS forall a. [a] -> [a] -> [a] ++ String key' String -> ShowS forall a. [a] -> [a] -> [a] ++ String value' keyl :: FieldSize keyl = Key -> FieldSize B.length Key key valuel :: FieldSize valuel = Key -> FieldSize B.length Key value key' :: String key' = Key -> String BU.toString Key key value' :: String value' = Key -> String BU.toString Key value getEntryLength :: Entry -> Int getEntryLength :: Entry -> Int getEntryLength (Entry Checksum _ FieldSize _ FieldSize ksize FieldSize vsize Key _ Key _) = FieldSize -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral (FieldSize -> Int) -> FieldSize -> Int forall a b. (a -> b) -> a -> b $ FieldSize 4 FieldSize -> FieldSize -> FieldSize forall a. Num a => a -> a -> a + FieldSize 8 FieldSize -> FieldSize -> FieldSize forall a. Num a => a -> a -> a + FieldSize 8 FieldSize -> FieldSize -> FieldSize forall a. Num a => a -> a -> a + FieldSize 8 FieldSize -> FieldSize -> FieldSize forall a. Num a => a -> a -> a + FieldSize ksize FieldSize -> FieldSize -> FieldSize forall a. Num a => a -> a -> a + FieldSize vsize matchChecksum :: Entry -> Bool matchChecksum :: Entry -> Bool matchChecksum (Entry Checksum checksum FieldSize timestamp FieldSize ksize FieldSize vsize Key k Key v) = Checksum checksum Checksum -> Checksum -> Bool forall a. Eq a => a -> a -> Bool == Checksum checksum' where checksum' :: Checksum checksum' = Key -> Checksum forall a. CRC32 a => a -> Checksum crc32 (Key -> Checksum) -> Key -> Checksum forall a b. (a -> b) -> a -> b $ String -> Key BU.fromString (String -> Key) -> String -> Key forall a b. (a -> b) -> a -> b $ FieldSize -> String forall a. Show a => a -> String show FieldSize timestamp String -> ShowS forall a. [a] -> [a] -> [a] ++ FieldSize -> String forall a. Show a => a -> String show FieldSize ksize String -> ShowS forall a. [a] -> [a] -> [a] ++ FieldSize -> String forall a. Show a => a -> String show FieldSize vsize String -> ShowS forall a. [a] -> [a] -> [a] ++ Key -> String BU.toString Key k String -> ShowS forall a. [a] -> [a] -> [a] ++ Key -> String BU.toString Key v