Still facing a QuickCheck failure.
KNSI575VAW6HRCZYXOEPQ4DTSML4EORML5MV4DJBRKE7TXCPS4EAC
OV5AKJHA773ETIJPTMQ7K64U7BRQE34OXJ6FJNH6TZG22WS5QTIAC
IZEVQF627FA7VV25KJAWYWGGC35LZUUBBQRPN5ZAINTQLPEDRTEAC
FD7SV5I6VCW27HZ3T3K4MMGB2OYGJTPKFFA263TNTAMRJGQJWVNAC
7KZP4RHZ3QSYTPPQ257A65Z5UPX44TF2LAI2U5EMULQCLDCEUK2AC
A6HKMINBNGQLLX4QJMYWKQ4JAEHVJ4HIRVDKPPDI3FJUO2AAB7OQC
EZQG2APB36DDMIAYDPPDGOIXOD7K2RZZSGC2NKGZIHB2HZBTW7EQC
NVOCQVASZWTKQJG7GPH7KHKZZR7NUG4WLV5YY4KAIRPCJRWCZPIAC
TLQ72DSJD7GGPWN6HGBHAVPBRQFKEQ6KSK43U7JWWID4ZWAF47JAC
Y35QCWYW2OTZ27ZVTH2BA3XJTUCJ2WMLKU32ZCOCDY3AW7TIZXRAC
64C6AWH66FDKU6UE6Z6JPX2J2GBM2JOPTH2GL6LHKAIUBGNGDZ5AC
5DRIWGLUKMQZU2ZPBXSTLAWJKAMOD5YXAHM5LEDQHDFGYYLHWCDQC
SCXG6TJWYIPRUMT27KGKIIF6FYKTUTY74UNZ2FQTT63XZ6HIF3AAC
RSEB2NFGUBTFESE5BJKDUVQL5Y5ZVGY5O4CJX2LNP63MS3NRHHZQC
GKGVYBZGPJXO7N7GLHLRNYQPXFHBQSNQN53OKRFCXLQEYDTC5I4QC
7XN3I3QJHYMKU2DCUXX34WQMSJ4ZJOWW7FME34EANO3E5W4Q632AC
SLL7262CJUE7TZDDZZXFROHCVVDA527WA4PHXCKEGZUJF2EN5MQAC
7DBNV3GV773FH5ZLQWFX4RBOS4Q3CIK2RYZNNABY3ZOETYZCXRNQC
4QX5E5ACVN57KJLCWOM4JEI6JSV4XZNCWVYPOTKSOMUW3SOMCNJAC
N4NDAZYTLSI2W22KT3SYXL257DBMSH3UT2BXOYM7LH7FSZAY4RLAC
BROSTG5KP3NUNLSYPVQID254TE47E5RKQAKLPIY7PGWETE6JNMTAC
I2KHGVD44KT4MQJXGCTVSQKMBO6TVCY72F26TLXGWRL6PHGF6RNQC
Z7KS5XHHC6PAMTVBHXY7KUSS3BWAOU6FSYIITUCFOOJZU4OUJHBAC
NMWWP4ZNOKHZKSJ6F5KYEREWXXR5F4UD35WOKI3EH42AZWVCTCJAC
OBFPJS2GHO2PEHBHGEHKIUOUAFIQHPIZXEVD2YIE3ZIE2PVMH5VAC
"event_t" -> maybe (returnError UnexpectedNull f "") (nameEvent . decodeUtf8) v
_ -> returnError Incompatible f "column was not of type event_t"
"event_t" ->
let err = UnexpectedNull (B.unpack tn)
(tableOid f)
(maybe "" B.unpack (name f))
"UTCTime -> LogEvent"
"columns of type event_t should not contain null values"
in maybe (conversionError err) (nameEvent . decodeUtf8) v
_ ->
let err = Incompatible (B.unpack tn)
(tableOid f)
(maybe "" B.unpack (name f))
"UTCTime -> LogEvent"
"column was not of type event_t"
in conversionError err
workEventParser :: RowParser WorkEvent
workEventParser = WorkEvent <$> fieldWith eventTypeParser <*> fieldWith utcParser <*> field
workEventParser :: RowParser LogEvent
workEventParser = fieldWith eventTypeParser <*> fieldWith utcParser
instance Ord EventType where
compare StartWork StopWork = GT
compare StopWork StartWork = LT
compare _ _ = EQ
instance Ord LogEvent where
compare (StartWork t0) (StopWork t1) = if t0 == t1 then GT else compare t0 t1
compare (StopWork t0) (StartWork t1) = if t0 == t1 then LT else compare t0 t1
compare (StartWork t0) (StartWork t1) = compare t0 t1
compare (StopWork t0) (StopWork t1) = compare t0 t1
data WorkEvent = WorkEvent
{ _eventType :: EventType
, _eventTime :: C.UTCTime
-- Permit the inclusion of arbitrary JSON data that may be refactored into
-- proper typed fields in the future.
, _eventMeta :: Maybe A.Value
} deriving (Show, Eq)
makeLenses ''WorkEvent
instance Ord WorkEvent where
compare a b =
let cv x = (x ^. eventTime, x ^. eventType)
in compare (cv a) (cv b)
type RawIndex = Map BtcAddr [Either WorkEvent Interval]
type NDT = C.NominalDiffTime
appendLogEntry idx (LogEntry k ev) =
let combine (WorkEvent StartWork t _) (WorkEvent StopWork t' _) | t' > t = Right $ Interval t t'
combine (e1 @ (WorkEvent StartWork _ _)) (e2 @ (WorkEvent StartWork _ _)) = Left $ max e1 e2
combine (e1 @ (WorkEvent StopWork _ _)) (e2 @ (WorkEvent StopWork _ _)) = Left $ min e1 e2
appendLogEntry idx (LogEntry k ev _) =
let combine (StartWork t) (StopWork t') | t' > t = Right $ Interval t t'
combine (e1 @ (StartWork _)) (e2 @ (StartWork _)) = Left $ min e1 e2 -- ignore redundant starts
combine (e1 @ (StopWork _)) (e2 @ (StopWork _)) = Left $ min e1 e2 -- ignore redundant ends
-- if it is possible to extend an interval at the top of the stack
-- because the end of that interval is the same
Just (Right ival : xs) -> case extension ival ev of
Just e' -> Left e' : xs
Nothing -> Left ev : Right ival : xs
-- if the top element of the stack is not an interval
let workEvent = WorkEvent evType timestamp $ A.decode requestBody
storeEv addr = runReaderT . recordEvent pid uid $ LogEntry addr workEvent
let logEntry addr = LogEntry addr (evCtr timestamp) (A.decode requestBody)
storeEv addr = runReaderT . recordEvent pid uid $ logEntry addr
newtype Intervals = Intervals (L.NonEmpty Interval)
buildIntervals :: T.UTCTime -> [NominalDiffTime] -> [Interval]
buildIntervals t (d : s : dx) =
let ival = I.interval t (t .+^ d)
in ival : buildIntervals (ival ^. end .+^ (abs s)) dx
buildIntervals _ _ = []
instance Arbitrary Intervals where
arbitrary = do
startTime <- arbitrary
let deltas = filter (> 0) <$> listOf arbitrary
intervals <- suchThat (buildIntervals startTime <$> deltas) (not.null)
pure . Intervals $ L.fromList intervals
let ivalEntries addr ival = [ LogEntry addr (WorkEvent StartWork (ival ^. start) Nothing)
, LogEntry addr (WorkEvent StopWork (ival ^. end) Nothing) ]
let ivalEntries addr ival = LogEntry addr <$> [StartWork (ival ^. start), StopWork (ival ^. end)]
<*> [Nothing]