From dc61968522c0b33c2f0c75d4eeecf231190d1825 Mon Sep 17 00:00:00 2001 From: Russoul Date: Fri, 20 Mar 2026 11:26:30 +0300 Subject: [PATCH] bench: Integrate cardano-timeseries-io --- bench/cardano-timeseries-io/CHANGELOG.md | 5 + bench/cardano-timeseries-io/LICENSE | 177 ++++ bench/cardano-timeseries-io/NOTICE | 13 + bench/cardano-timeseries-io/README.md | 31 + .../app/Cardano/Timeseries.hs | 38 + .../app/Cardano/Timeseries/CLI.hs | 29 + .../app/Cardano/Timeseries/Common.hs | 81 ++ bench/cardano-timeseries-io/bench/Bench.hs | 67 ++ .../cardano-timeseries-io.cabal | 168 ++++ .../data/6nodes_4hours_1mininterval.cbor.gz | Bin 0 -> 390611 bytes bench/cardano-timeseries-io/docs/domain.txt | 19 + bench/cardano-timeseries-io/docs/elab.txt | 143 +++ .../docs/sre-expressions.txt | 47 + bench/cardano-timeseries-io/docs/typing.txt | 512 ++++++++++ .../cardano-timeseries-io/examples/query1.txt | 7 + .../examples/query10.txt | 9 + .../examples/query11.txt | 4 + .../examples/query12.txt | 6 + .../cardano-timeseries-io/examples/query2.txt | 2 + .../cardano-timeseries-io/examples/query3.txt | 1 + .../cardano-timeseries-io/examples/query4.txt | 1 + .../cardano-timeseries-io/examples/query5.txt | 1 + .../cardano-timeseries-io/examples/query6.txt | 1 + .../cardano-timeseries-io/examples/query7.txt | 2 + .../cardano-timeseries-io/examples/query8.txt | 1 + .../cardano-timeseries-io/examples/query9.txt | 6 + .../src/Cardano/Timeseries/API.hs | 50 + .../src/Cardano/Timeseries/AsText.hs | 10 + .../src/Cardano/Timeseries/Component.hs | 138 +++ .../src/Cardano/Timeseries/Component/Trace.hs | 91 ++ .../src/Cardano/Timeseries/Component/Types.hs | 21 + .../Cardano/Timeseries/Domain/Identifier.hs | 14 + .../src/Cardano/Timeseries/Domain/Instant.hs | 43 + .../src/Cardano/Timeseries/Domain/Interval.hs | 12 + .../Cardano/Timeseries/Domain/Timeseries.hs | 115 +++ .../src/Cardano/Timeseries/Domain/Types.hs | 21 + .../src/Cardano/Timeseries/Elab.hs | 894 ++++++++++++++++++ .../src/Cardano/Timeseries/Elab/Expr.hs | 233 +++++ .../src/Cardano/Timeseries/Elab/Expr/Head.hs | 27 + .../Cardano/Timeseries/Elab/Expr/Parser.hs | 376 ++++++++ .../src/Cardano/Timeseries/Elab/Resolve.hs | 119 +++ .../src/Cardano/Timeseries/Elab/Typing.hs | 108 +++ .../src/Cardano/Timeseries/Elab/Unify.hs | 94 ++ .../Cardano/Timeseries/Import/PlainCBOR.hs | 58 ++ .../src/Cardano/Timeseries/Interp.hs | 365 +++++++ .../Timeseries/Interp/BinaryArithmeticOp.hs | 47 + .../Timeseries/Interp/BinaryRelation.hs | 88 ++ .../src/Cardano/Timeseries/Interp/Config.hs | 12 + .../src/Cardano/Timeseries/Interp/Expect.hs | 72 ++ .../src/Cardano/Timeseries/Interp/Expr.hs | 103 ++ .../Cardano/Timeseries/Interp/Statistics.hs | 31 + .../src/Cardano/Timeseries/Interp/Types.hs | 16 + .../src/Cardano/Timeseries/Interp/Value.hs | 57 ++ .../src/Cardano/Timeseries/Store.hs | 41 + .../src/Cardano/Timeseries/Store/Flat.hs | 74 ++ .../Cardano/Timeseries/Store/Flat/Parser.hs | 62 ++ .../src/Cardano/Timeseries/Store/Tree.hs | 90 ++ .../src/Cardano/Timeseries/Util.hs | 31 + cabal.project | 1 + 59 files changed, 4885 insertions(+) create mode 100644 bench/cardano-timeseries-io/CHANGELOG.md create mode 100644 bench/cardano-timeseries-io/LICENSE create mode 100644 bench/cardano-timeseries-io/NOTICE create mode 100644 bench/cardano-timeseries-io/README.md create mode 100644 bench/cardano-timeseries-io/app/Cardano/Timeseries.hs create mode 100644 bench/cardano-timeseries-io/app/Cardano/Timeseries/CLI.hs create mode 100644 bench/cardano-timeseries-io/app/Cardano/Timeseries/Common.hs create mode 100644 bench/cardano-timeseries-io/bench/Bench.hs create mode 100644 bench/cardano-timeseries-io/cardano-timeseries-io.cabal create mode 100644 bench/cardano-timeseries-io/data/6nodes_4hours_1mininterval.cbor.gz create mode 100644 bench/cardano-timeseries-io/docs/domain.txt create mode 100644 bench/cardano-timeseries-io/docs/elab.txt create mode 100644 bench/cardano-timeseries-io/docs/sre-expressions.txt create mode 100644 bench/cardano-timeseries-io/docs/typing.txt create mode 100644 bench/cardano-timeseries-io/examples/query1.txt create mode 100644 bench/cardano-timeseries-io/examples/query10.txt create mode 100644 bench/cardano-timeseries-io/examples/query11.txt create mode 100644 bench/cardano-timeseries-io/examples/query12.txt create mode 100644 bench/cardano-timeseries-io/examples/query2.txt create mode 100644 bench/cardano-timeseries-io/examples/query3.txt create mode 100644 bench/cardano-timeseries-io/examples/query4.txt create mode 100644 bench/cardano-timeseries-io/examples/query5.txt create mode 100644 bench/cardano-timeseries-io/examples/query6.txt create mode 100644 bench/cardano-timeseries-io/examples/query7.txt create mode 100644 bench/cardano-timeseries-io/examples/query8.txt create mode 100644 bench/cardano-timeseries-io/examples/query9.txt create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/API.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/AsText.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Component.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Component/Trace.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Component/Types.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Identifier.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Instant.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Interval.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Timeseries.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Types.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr/Head.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr/Parser.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Resolve.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Typing.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Unify.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Import/PlainCBOR.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/BinaryArithmeticOp.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/BinaryRelation.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Config.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Expect.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Expr.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Statistics.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Types.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Value.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Store.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Flat.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Flat/Parser.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Tree.hs create mode 100644 bench/cardano-timeseries-io/src/Cardano/Timeseries/Util.hs diff --git a/bench/cardano-timeseries-io/CHANGELOG.md b/bench/cardano-timeseries-io/CHANGELOG.md new file mode 100644 index 00000000000..872cc41f136 --- /dev/null +++ b/bench/cardano-timeseries-io/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for cardano-timeseries-io + +## 1.0.0 -- March 2026 + +* First version. diff --git a/bench/cardano-timeseries-io/LICENSE b/bench/cardano-timeseries-io/LICENSE new file mode 100644 index 00000000000..f433b1a53f5 --- /dev/null +++ b/bench/cardano-timeseries-io/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/bench/cardano-timeseries-io/NOTICE b/bench/cardano-timeseries-io/NOTICE new file mode 100644 index 00000000000..571e2b91fed --- /dev/null +++ b/bench/cardano-timeseries-io/NOTICE @@ -0,0 +1,13 @@ +Copyright 2023 Input Output Global Inc (IOG), 2023-2026 Intersect. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/bench/cardano-timeseries-io/README.md b/bench/cardano-timeseries-io/README.md new file mode 100644 index 00000000000..120368aaa1f --- /dev/null +++ b/bench/cardano-timeseries-io/README.md @@ -0,0 +1,31 @@ +# Cardano Timeseries I/O + +## What it does + +The primary goal of the project is to serve as a standalone library for `cardano-tracer`, providing realtime metric storage & query. + +The library exposes the following components: +- An interface of metric stores together with multiple implementations. +- A low-level unambiguous language & its interpreter against a metric store — for querying metrics. +- A high-level user-facing language & its elaborator to the low-level one. + +On top of the library the project provides a simple CLI for reading a store off disk & executing a query against it, optionally interactively. + +## CLI Syntax + +``` +Usage: cardano-timeseries-io FILE + ((-q|--query QUERY) | (-f|--file FILE) | + (-i|--interactive)) + + Run a query against a metric store + +Available options: + -q,--query QUERY Execute the query + -f,--file FILE Execute the file + -i,--interactive Enter REPL + -h,--help Show this help text +``` + +## Build flags + - _profiling_ for enabling GHC profiling support. diff --git a/bench/cardano-timeseries-io/app/Cardano/Timeseries.hs b/bench/cardano-timeseries-io/app/Cardano/Timeseries.hs new file mode 100644 index 00000000000..9e7bee308fd --- /dev/null +++ b/bench/cardano-timeseries-io/app/Cardano/Timeseries.hs @@ -0,0 +1,38 @@ +{-# LANGUAGE OverloadedRecordDot #-} + +module Main where + +import Cardano.Timeseries.API +import Cardano.Timeseries.CLI +import Cardano.Timeseries.Common + +import Data.Foldable +import qualified Data.Map as Map +import Data.Text (Text) +import qualified Data.Text.IO as Text +import Options.Applicative + +interpConfig :: Config +interpConfig = Config {defaultRangeSamplingRateMillis = 15 * 1000} + +now :: Timestamp +now = 0 + +main :: IO () +main = do + cmd <- execParser parseCommand + store <- readStore cmd.store + putStrLn "Metrics:" + for_ (Map.keys store) $ \k -> + Text.putStrLn (" — " <> k <> "[" <> showMaybe (earliest store k) <> "ms; " <> showMaybe (latest store k) <> "ms]") + case cmd.mode of + Interactive -> repl store interpConfig now + ExecuteQuery query -> printExecutionResult $ execute store interpConfig now query + ExecuteFile file -> do + query <- Text.readFile file + printExecutionResult $ execute store interpConfig now query + where + showMaybe :: Show a => Maybe a -> Text + showMaybe Nothing = "N/A" + showMaybe (Just x) = showT x + diff --git a/bench/cardano-timeseries-io/app/Cardano/Timeseries/CLI.hs b/bench/cardano-timeseries-io/app/Cardano/Timeseries/CLI.hs new file mode 100644 index 00000000000..e6a1b416a60 --- /dev/null +++ b/bench/cardano-timeseries-io/app/Cardano/Timeseries/CLI.hs @@ -0,0 +1,29 @@ +module Cardano.Timeseries.CLI(Mode(..), Command(..), parseCommand) where +import Data.Text (Text) +import Options.Applicative + +data Mode = ExecuteQuery Text | ExecuteFile FilePath | Interactive + +data Command = Command { + store :: FilePath, + mode :: Mode +} + +parseExecuteQuery :: Parser Mode +parseExecuteQuery = ExecuteQuery <$> option str (short 'q' <> long "query" <> metavar "QUERY" <> help "Execute the query") + +parseExecuteFile :: Parser Mode +parseExecuteFile = ExecuteFile <$> option str (short 'f' <> long "file" <> metavar "FILE" <> help "Execute the file") + +parseInteractive :: Parser Mode +parseInteractive = flag' Interactive (short 'i' <> long "interactive" <> help "Enter REPL") + +parseMode :: Parser Mode +parseMode = parseExecuteQuery <|> parseExecuteFile <|> parseInteractive + +parseStore :: Parser FilePath +parseStore = argument str (metavar "FILE") + +parseCommand :: ParserInfo Command +parseCommand = info (Command <$> parseStore <*> parseMode <**> helper) + (fullDesc <> progDesc "Run a query against a metric store") diff --git a/bench/cardano-timeseries-io/app/Cardano/Timeseries/Common.hs b/bench/cardano-timeseries-io/app/Cardano/Timeseries/Common.hs new file mode 100644 index 00000000000..bffbebf8b3d --- /dev/null +++ b/bench/cardano-timeseries-io/app/Cardano/Timeseries/Common.hs @@ -0,0 +1,81 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE FlexibleContexts #-} +{- HLINT ignore "Use print" -} + +module Cardano.Timeseries.Common(readStore, repl, printInterpResult, printExecutionResult) where + +import Cardano.Logging.Resources (ResourceStats, Resources (..), readResourceStats) +import Cardano.Timeseries.API +import Cardano.Timeseries.Import.PlainCBOR + +import Control.DeepSeq (force) +import Control.Monad (forever, when) +import Control.Monad.Except (runExceptT) +import Control.Monad.State.Strict (evalState) +import Data.Functor (void) +import qualified Data.Text as Text +import qualified Data.Text.IO as Text +import System.Exit (die) +import System.FilePath (takeExtension) +import System.IO (hFlush, stdout) +import Text.Megaparsec hiding (count) +import Text.Megaparsec.Char (newline, space, space1) + +statsEnabled :: Bool +#ifdef STATS +statsEnabled = True +#else +statsEnabled = False +#endif + +printStats :: ResourceStats -> IO () +printStats stats = + putStrLn $ "Alloc: " <> show ((fromIntegral (rAlloc stats) :: Double) / 1024 / 1024) <> "MB\n" + <> "Live: " <> show ((fromIntegral (rLive stats) :: Double) / 1024 / 1024) <> "MB\n" + <> "Heap: " <> show ((fromIntegral (rHeap stats) :: Double) / 1024 / 1024) <> "MB\n" + <> "RSS: " <> show ((fromIntegral (rRSS stats) :: Double) / 1024 / 1024) <> "MB" + +printInterpResult :: Either InterpError Value -> IO () +printInterpResult (Left err) = Text.putStrLn $ asText err +printInterpResult (Right ok) = print ok + +printExecutionResult :: Either ExecutionError Value -> IO () +printExecutionResult (Left err) = Text.putStrLn $ asText err +printExecutionResult (Right ok) = print ok + +repl :: Store s Double => s -> Config -> Timestamp -> IO () +repl store interpCfg now = forever $ do + putStrLn "----------" + when statsEnabled $ do + Just stats <- readResourceStats + printStats stats + putStrLn $ "Number of store entries: " <> show (count store) + putStrLn "----------" + putStr "> " + hFlush stdout + queryString <- Text.getLine + case parse (expr <* space <* eof) "input" queryString of + Left err -> putStrLn (errorBundlePretty err) + Right surfaceQuery -> do + case evalState (runExceptT (elab surfaceQuery)) initialSt of + Left err -> Text.putStrLn err + Right query -> do + Text.putStrLn (showT query) + printInterpResult (evalState (runExceptT $ interp interpCfg store mempty query now) 0) + +whitespace :: Parser () +whitespace = skipMany (try space1 <|> void newline) + +readStore :: FilePath -> IO (Tree Double) +readStore path | takeExtension path == ".cbor" = do + content <- readFileSnapshots path + putStrLn "Read the snapshots CBOR file!" + let store = force $ fromFlat $ snapshotsToFlatStore content + putStrLn "Created a store from CBOR!" + pure store +readStore path | takeExtension path == ".txt" = do + content <- Text.lines <$> Text.readFile path + case traverse (parse (point double <* whitespace <* eof) "input") content of + Left err -> die (errorBundlePretty err) + Right store -> pure $ fromFlat store +readStore path = die $ "Unknown extension: " <> takeExtension path diff --git a/bench/cardano-timeseries-io/bench/Bench.hs b/bench/cardano-timeseries-io/bench/Bench.hs new file mode 100644 index 00000000000..51907ba8b2f --- /dev/null +++ b/bench/cardano-timeseries-io/bench/Bench.hs @@ -0,0 +1,67 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + +import Cardano.Timeseries.AsText (showT) +import Cardano.Timeseries.Elab (elab, initialSt) +import qualified Cardano.Timeseries.Elab.Expr.Parser as Surface.Parser +import Cardano.Timeseries.Import.PlainCBOR +import Cardano.Timeseries.Interp (interp) +import Cardano.Timeseries.Interp.Config +import Cardano.Timeseries.Interp.Expr (Expr) +import Cardano.Timeseries.Interp.Value (Value) +import Cardano.Timeseries.Store +import Cardano.Timeseries.Store.Tree (fromFlat) + +import Codec.Compression.GZip as GZip (decompress) +import Codec.Serialise (deserialise) +import Control.Monad.Except (runExceptT) +import Control.Monad.State.Strict (evalState) +import qualified Data.ByteString.Lazy as BL (readFile) +import Data.Text (Text) +import qualified Data.Text.IO as Text +import Text.Megaparsec hiding (count) +import Text.Megaparsec.Char (space) + +import Criterion.Main + +-- Given a snapshots file +-- Given a query string +-- Benchmark evaluation of the query on flat & tree stores. + +snapshotsFile :: FilePath +snapshotsFile = "data/6nodes_4hours_1mininterval.cbor.gz" + +query :: Text +query = "\ + \let start = epoch + 1762173870000ms in \ + \let period = 10m in \ + \let F = Forge_forged_counter[start; start + period] in \ + \increase F" + +interpConfig :: Config +interpConfig = Config {defaultRangeSamplingRateMillis = 15 * 1000} + +action :: Store s Double => (s, Expr) -> Value +action (store, q) = + let Right !x = evalState (runExceptT $ interp interpConfig store mempty q 0) 0 in x + +main :: IO () +main = do + content :: [Snapshot] <- + deserialise . GZip.decompress <$> BL.readFile snapshotsFile + let flatStore = snapshotsToFlatStore content + let treeStore = fromFlat flatStore + case parse (Surface.Parser.expr <* space <* eof) "input" query of + Left err -> putStrLn (errorBundlePretty err) + Right surfaceQuery -> do + case evalState (runExceptT (elab surfaceQuery)) initialSt of + Left err -> Text.putStrLn err + Right !q -> do + Text.putStrLn (showT q) + defaultMain + [ + bench "flat" $ nf action (flatStore, q), + bench "tree" $ nf action (treeStore, q) + ] diff --git a/bench/cardano-timeseries-io/cardano-timeseries-io.cabal b/bench/cardano-timeseries-io/cardano-timeseries-io.cabal new file mode 100644 index 00000000000..974ab239867 --- /dev/null +++ b/bench/cardano-timeseries-io/cardano-timeseries-io.cabal @@ -0,0 +1,168 @@ +cabal-version: 3.4 +name: cardano-timeseries-io +description: Cardano Timeseries Input/Output for realtime metric storage & query. +version: 1.0.0 +category: Cardano + Metrics +copyright: 2026 Intersect. +license: Apache-2.0 +license-files: LICENSE + NOTICE +author: Ruslan Feizerakhmanov +maintainer: ruslan.feizerakhmanov@iohk.io +build-type: Simple +extra-doc-files: CHANGELOG.md + README.md + examples/*.txt + docs/*.txt + +flag profiling + description: Enable profiling + default: False + manual: True + +common common + ghc-options: + -Wall + + if impl(ghc >= 9.8) + ghc-options: + -Wno-x-partial + + if flag(profiling) + ghc-options: + -fno-prof-auto + + default-language: Haskell2010 + + default-extensions: + LambdaCase + NamedFieldPuns + OverloadedStrings + + -- NB.: This package is strict Haskell! + Strict + +library + import: common + hs-source-dirs: src + + build-depends: + , aeson + , async + , base + , containers + , deepseq + , megaparsec + , mtl + , scientific + , serialise + , statistics + , stm + , text + , time + , trace-dispatcher >= 2.11.0 && < 3 + , vector + + exposed-modules: + , Cardano.Timeseries.API + + , Cardano.Timeseries.AsText + + , Cardano.Timeseries.Component + , Cardano.Timeseries.Component.Trace + , Cardano.Timeseries.Component.Types + + , Cardano.Timeseries.Domain.Identifier + , Cardano.Timeseries.Domain.Instant + , Cardano.Timeseries.Domain.Interval + , Cardano.Timeseries.Domain.Timeseries + , Cardano.Timeseries.Domain.Types + + , Cardano.Timeseries.Import.PlainCBOR + + , Cardano.Timeseries.Interp + , Cardano.Timeseries.Interp.Config + , Cardano.Timeseries.Interp.Expr + , Cardano.Timeseries.Interp.Types + , Cardano.Timeseries.Interp.Value + + , Cardano.Timeseries.Store + , Cardano.Timeseries.Store.Flat + , Cardano.Timeseries.Store.Flat.Parser + , Cardano.Timeseries.Store.Tree + + , Cardano.Timeseries.Elab + , Cardano.Timeseries.Elab.Expr + , Cardano.Timeseries.Elab.Expr.Parser + + other-modules: + , Cardano.Timeseries.Elab.Expr.Head + , Cardano.Timeseries.Elab.Resolve + , Cardano.Timeseries.Elab.Typing + , Cardano.Timeseries.Elab.Unify + + , Cardano.Timeseries.Interp.BinaryArithmeticOp + , Cardano.Timeseries.Interp.BinaryRelation + , Cardano.Timeseries.Interp.Expect + , Cardano.Timeseries.Interp.Statistics + + , Cardano.Timeseries.Util + +-- Only used by the executable +flag stats + description: Enable rendering of RTS statistics in CLI + default: False + manual: True + +executable cardano-timeseries-io + import: common + ghc-options: -rtsopts + hs-source-dirs: app + main-is: Cardano/Timeseries.hs + + if flag(stats) + cpp-options: + -DSTATS + + other-modules: + , Cardano.Timeseries.Common + , Cardano.Timeseries.CLI + + build-depends: + , base + , cardano-timeseries-io + , containers + , deepseq + , filepath + , megaparsec + , mtl + , optparse-applicative + , serialise + , statistics + , text + , time + , trace-resources + , vector + +benchmark cardano-timeseries-io-bench + import: common + type: exitcode-stdio-1.0 + hs-source-dirs: bench + main-is: Bench.hs + + build-depends: + , base + , bytestring + , cardano-timeseries-io + , containers + , criterion + , megaparsec + , mtl + , serialise + , statistics + , text + , time + , trace-resources + , vector + , zlib diff --git a/bench/cardano-timeseries-io/data/6nodes_4hours_1mininterval.cbor.gz b/bench/cardano-timeseries-io/data/6nodes_4hours_1mininterval.cbor.gz new file mode 100644 index 0000000000000000000000000000000000000000..060541ad0f9113dbb508bb85199dd9104e38c99e GIT binary patch literal 390611 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
CA+d#@ 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%0AuF%IoKY%`EZbG%I) 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

%ZDw%?(w2b2^GDsxpXMnYoknsu}2sqN@=O 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 jmnd%tNER+^ t +t t +fst t +snd t +(t, t) +t == t (~) +t != t (~) +t < t (~) +t <= t (~) +t > t (~) +t >= t (~) +t + t (~) +t - t (~) +t * t (~) +t / t (~) +true +false +!t +t && t +t || t +ms +s +min +h +epoch +now +to_scalar t +t[t; t] +t[t; t : t] +filter_by_label {s = s, ..., s = s} t +max t +min t +avg t +filter t t +join t t +map t t +abs t +increase t +rate t +avg_over_time t +sum_over_time t +quantile_over_time t t +unless t t +quantile_by (s, ..., s) t t +x +metrics + + +// General elaboration jugdement + ~> : + +// Binary relation elaboration jugdement + ⊦ ( : ) ( : ) ~> : + +// Binary arithmetic operator elaboration jugdement + ⊦ ( : ) ( : ) ~> : + +// "to_scalar" elaboration judgement + ⊦ to_scalar ( : ) ~> + + +Γ ⊦ t ~> ?x : A +Γ (x : A) ⊦ e ~> ?y : B +=========================================== +Γ ⊦ let x = t in e ~> let x = ?x in ?y : B + + +Γ (x : A) ⊦ t ~> ?z : B +================================= +Γ ⊦ \x -> t ~> \x -> ?z : A -> B + + +Γ = Γ₀ (x : C) Γ₁ +Γ ⊦ ?x := x : C +================= +Γ ⊦ x ~> ?x : C + + +x ∉ Γ +Γ ⊦ ?x ≔ x : Timestamp -> Scalar // Assumes existence of x in the metric store +================================== +Γ ⊦ x ~> ?x : Timestamp -> Scalar + + +Γ ⊦ t ~> ?z : (A, B) +======================== +Γ ⊦ fst t ~> fst ?z : A + + +Γ ⊦ t ~> ?z : (A, B) +======================== +Γ ⊦ snd t ~> snd ?z : B + + +Γ ⊦ a ~> ?x : A +Γ ⊦ b ~> ?y : B +================================ +Γ ⊦ (a, b) ~> (?x, ?y) : (A, B) + + +Γ ⊦ ?a : ?A +Γ ⊦ ?b : ?B +Γ ⊦ a ~> ?a : ?A +Γ ⊦ b ~> ?b : ?B +Γ ⊦ (?a : ?A) rel (?b : ?B) ~> ?r : C +===================================== +Γ ⊦ a rel b ~> ?r : C + + +Γ ⊦ ?r := ⟦rel⟧ a b : Bool +============================================ +Γ ⊦ ?r : Bool +Γ ⊦ (a : Scalar) rel (b : Scalar) ~> ?r : Bool + + +Γ ⊦ ?r ≔ lte_instant_vector a b : InstantVector Scalar +======================================================================== +Γ ⊦ a : InstantVector Scalar <= b : Scalar ~> ?r : InstantVector Scalar + + +Γ ⊦ ?a : ?A +Γ ⊦ ?b : ?B +Γ ⊦ a ~> ?a : ?A +Γ ⊦ b ~> ?b : ?B +Γ ⊦ (?a : ?A) op (?b : ?B) ~> ?r : C +==================================== +Γ ⊦ a op b ~> ?r : C + + +Γ ⊦ ?r ≔ ⟦rel⟧ a b : Scalar +============================================== +Γ ⊦ (a : Scalar) rel (b : Scalar) ~> ?r : Scalar + + +Γ ⊦ s ~> ?s : ?A +Γ ⊦ to_scalar (?s : ?A) ~> ?r +============================= +Γ ⊦ to_scalar s ~> ?r : Scalar diff --git a/bench/cardano-timeseries-io/docs/sre-expressions.txt b/bench/cardano-timeseries-io/docs/sre-expressions.txt new file mode 100644 index 00000000000..9312b99f127 --- /dev/null +++ b/bench/cardano-timeseries-io/docs/sre-expressions.txt @@ -0,0 +1,47 @@ +// PromQL +( + (abs(max(${blockMetric}{environment="${env}"}) - ${blockMetric}{environment="${env}"}) > bool ${toString lagBlocks}) + - + (abs(max(${slotMetric}{environment="${env}"}) - on() group_right() ${slotMetric}{environment="${env}"}) < bool ${toString lagSeconds}) +) == 1 + +//PromQL +${kesPeriodsRemaining} <= ${toString periodNotice} + + +//PromQL +increase(cardano_node_metrics_Forge_forged_int[24h]) == 0 + +//PromQL +rate(cardano_node_metrics_slotsMissedNum_int[5m]) * 1 > 0.5 + +//PromQL +avg_over_time(netdata_statsd_cardano_node_ping_latency_ms_gauge_value_average[5m]) > 500 + + +//PromQL +avg(quantile_over_time(0.95, cardano_node_metrics_blockadoption_forgeDelay_real[6h])) >= 4.5 + + +//PromQL +100 * avg(avg_over_time(cardano_node_metrics_blockfetchclient_blocksize[6h]) / 90112) > ${highBlockUtilization} + + +//PromQL +cardano_node_metrics_blockfetchclient_blockdelay_cdfFive < 0.90 + + +//PromQL +round(increase((time() - cardano_node_metrics_nodeStartTime_int < bool 300)[1h:1m])) > 1 + + +//PromQL +(sum_over_time((cardano_node_metrics_blockNum_int != bool 0)[360m:1m]) < bool 350) > 0 unless cardano_node_metrics_blockNum_int" + + +//PromQL +100 * quantile by(environment) (0.2, (cardano_node_metrics_density_real * 20)) < ${chainDensityVeryLow} + + +//PromQL +100 * quantile by(environment) (0.2, (cardano_node_metrics_density_real{environment!~"preview"} * 20)) < ${chainDensityLow} diff --git a/bench/cardano-timeseries-io/docs/typing.txt b/bench/cardano-timeseries-io/docs/typing.txt new file mode 100644 index 00000000000..32447873d63 --- /dev/null +++ b/bench/cardano-timeseries-io/docs/typing.txt @@ -0,0 +1,512 @@ + +x ::= + +n ::= + +s, s' ::= + +// Label +l ::= s + +// Set of labels +l̄ ::= (l, ..., l) + +// Label constraint +c ::= l = s | l != s + +// Set of label constraints +c̄ ::= {c, ..., c} + +// Types +A, B, C, T ::= InstantVector T | RangeVector T | Scalar | Bool | Timestamp | Duration | (T, T) | T -> T | Text + +// Contexts +Γ ::= ε | Γ (x ≔ t : T) | Γ (x : T) + +// Terms +t, f, e, a, b ::= x + | (t, t) + | \x -> t + | let x = t in t + | fst t + | snd t + | eq_scalar t t + | not_eq_scalar t t + | eq_bool t t + | not_eq_bool t t + | lt_bool t t + | lte_bool t t + | gt_bool t t + | gte_bool t t + | lt_scalar t t + | lte_scalar t t + | gt_scalar t t + | gte_scalar t t + | add_scalar t t + | sub_scalar t t + | mul_scalar t t + | div_scalar t t + | not t + | and t t + | or t t + | milliseconds n + | seconds n + | minutes n + | hours n + | epoch + | now + | rewind t t + | fast_forward t t + | timestamp_to_scalar t + | bool_to_scalar t + | round_scalar t + | abs t + | range t t t + | range t t t t + | filter_by_label t c̄ + | max t + | min t + | avg t + | filter t + | join t t + | map t + | increase t + | rate t + | avg_over_time t + | sum_over_time t + | quantile_over_time t t + | unless t t + | eq_instant_vector_scalar t t + | not_eq_instant_vector_scalar t t + | lt_instant_vector_scalar t t + | lte_instant_vector_scalar t t + | gt_instant_vector_scalar t t + | gte_instant_vector_scalar t t + | add_instant_vector_scalar t t + | sub_instant_vector_scalar t t + | mul_instant_vector_scalar t t + | div_instant_vector_scalar t t + | instant_vector_to_scalar t + | quantile_by t t + | metrics + +┌──────┐ +│A type│ +└──────┘ + +A type +---------------------- +InstantVector A type + + +A type +-------------------- +RangeVector A type + + +Scalar type + + +Bool type + + +A type +B type +----------- +(A, B) type + +A type +B type +------ +A -> B + + +Timestamp type + + +Duration type + +Text type + +┌──────┐ +│Γ ctx │ +└──────┘ + +ε ctx + +Γ ctx +A type +------------- +Γ (x : A) ctx + +Γ ⊦ t : A +----------------- +Γ (x ≔ t : A) ctx + +┌─────────┐ +│Γ ctx │ +│A type │ +│---------│ +│Γ ⊦ t : A│ +└─────────┘ + + +--------------------- ✔ +Γ₀ (x : C) Γ₁ ⊦ x : C + + +------------------------- ✔ +Γ₀ (x ≔ t : C) Γ₁ ⊦ x : C + + +x ∈ metric-store +----------------------------------------- ✔ +Γ ⊦ x : Timestamp -> InstantVector Scalar + + +Γ (x := t : A) ⊦ e : B +---------------------- ✔ +Γ ⊦ let x = t in e : B + + +(x : A) ⊦ t : B +-------------------- ✔ +Γ ⊦ \x -> t : A -> B + + +Γ ⊦ t : (A, B) +-------------- ✔ +Γ ⊦ fst t : A + + +Γ ⊦ t : (A, B) +-------------- ✔ +Γ ⊦ snd t : B + + +Γ ⊦ a : A +Γ ⊦ b : B +------------------- ✔ +Γ ⊦ (a, b) : (A, B) + + +Γ ⊦ a : Bool +Γ ⊦ b : Bool +---------------------- ✔ +Γ ⊦ eq_bool a b : Bool + + +Γ ⊦ a : Bool +Γ ⊦ b : Bool +-------------------------- ✔ +Γ ⊦ not_eq_bool a b : Bool + + +Γ ⊦ a : Bool +Γ ⊦ b : Bool +-------------------------- ✔ +Γ ⊦ lt_bool a b : Bool + + +Γ ⊦ a : Bool +Γ ⊦ b : Bool +-------------------------- ✔ +Γ ⊦ lte_bool a b : Bool + + +Γ ⊦ a : Bool +Γ ⊦ b : Bool +-------------------------- ✔ +Γ ⊦ gt_bool a b : Bool + + +Γ ⊦ a : Bool +Γ ⊦ b : Bool +-------------------------- ✔ +Γ ⊦ gte_bool a b : Bool + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +------------------------ ✔ +Γ ⊦ eq_scalar a b : Bool + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +---------------------------- ✔ +Γ ⊦ not_eq_scalar a b : Bool + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +------------------------ ✔ +Γ ⊦ lt_scalar a b : Bool + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +------------------------- ✔ +Γ ⊦ lte_scalar a b : Bool + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +------------------------ ✔ +Γ ⊦ gt_scalar a b : Bool + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +------------------------- ✔ +Γ ⊦ gte_scalar a b : Bool + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +--------------------------- ✔ +Γ ⊦ add_scalar a b : Scalar + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +--------------------------- ✔ +Γ ⊦ sub_scalar a b : Scalar + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +--------------------------- ✔ +Γ ⊦ mul_scalar a b : Scalar + + +Γ ⊦ a : Scalar +Γ ⊦ b : Scalar +--------------------------- ✔ +Γ ⊦ div_scalar a b : Scalar + + +Γ ⊦ a : Bool +---------------- ✔ +Γ ⊦ not a : Bool + + +Γ ⊦ a : Bool +Γ ⊦ b : Bool +------------------ ✔ +Γ ⊦ and a b : Bool + + +Γ ⊦ a : Bool +Γ ⊦ b : Bool +----------------- ✔ +Γ ⊦ or a b : Bool + + +n integer // integer literal +----------------------------- ✔ +Γ ⊦ milliseconds n : Duration + + +n integer // integer literal +---------------------------- ✔ +Γ ⊦ seconds n : Duration + + +n integer // integer literal +---------------------------- ✔ +Γ ⊦ minutes n : Duration + + +n integer // integer literal + // Syntax hugar: h ✗ +----------------------------------- ✔ +Γ ⊦ hours n : Duration + + +Γ ⊦ epoch : Timestamp ✔ + + +Γ ⊦ now : Timestamp ✔ + + +Γ ⊦ t : Timestamp +Γ ⊦ d : Duration +-------------------------- ✔ +Γ ⊦ rewind t d : Timestamp + + +Γ ⊦ t : Timestamp +Γ ⊦ d : Duration +-------------------------------- ✔ +Γ ⊦ fast_forward t d : Timestamp + + +Γ ⊦ t : Timestamp +---------------------------------- ✔ +Γ ⊦ timestamp_to_scalar t : Scalar + + +Γ ⊦ t : Bool +----------------------------- ✔ +Γ ⊦ bool_to_scalar t : Scalar + + +// Given a continuous timeseries vector and an interval computes a discrete timeseries vector (range vector) +Γ ⊦ s : Timestamp -> InstantVector a +Γ ⊦ a : Timestamp +Γ ⊦ b : Timestamp +------------------------------------ ✔ +Γ ⊦ range s a b : RangeVector a + + +// More general version with a sampling rate +Γ ⊦ s : Timestamp -> InstantVector a +Γ ⊦ a : Timestamp +Γ ⊦ b : Timestamp +Γ ⊦ d : Duration +--------------------------------- ✔ +Γ ⊦ range s a b d : RangeVector a + + +// Takes a subset of instant vector `v` by keeping only those instants whose labels +// satisfy the constraints c̄ +Γ ⊦ v : InstantVector a +----------------------------------------- ✔ +Γ ⊦ filter_by_label c̄ v : InstantVector a + + +Γ ⊦ v : InstantVector Scalar +---------------------------- ✔ +Γ ⊦ max v : Scalar + + +Γ ⊦ v : InstantVector Scalar +---------------------------- ✔ +Γ ⊦ min v : Scalar + + +Γ ⊦ v : InstantVector Scalar +--------------------------- ✔ +Γ ⊦ avg v : Scalar + + +Γ ⊦ f : A -> Bool +Γ ⊦ v : InstantVector A +-------------------------------- ✔ +Γ ⊦ filter f v : InstantVector A + + +Γ ⊦ u : InstantVector A +Γ ⊦ v : InstantVector B +----------------------------------- // 1-to-1 match is assumed ✔ +Γ ⊦ join u v : InstantVector (A, B) + + +Γ ⊦ f : A -> B +Γ ⊦ v : InstantVector A +----------------------------- ✔ +Γ ⊦ map f u : InstantVector B + + +Γ ⊦ t : Scalar +--------------------------- ✔ +Γ ⊦ round_scalar t : Scalar + + +Γ ⊦ t : Scalar +------------------ ✔ +Γ ⊦ abs t : Scalar + + +Γ ⊦ r : RangeVector Scalar +------------------------------------ ✔ +Γ ⊦ increase r : InstantVector Scalar + + +Γ ⊦ r : RangeVector Scalar +--------------------------------- ✔ +Γ ⊦ rate r : InstantVector Scalar + + +Γ ⊦ r : RangeVector Scalar +------------------------------------------ ✔ +Γ ⊦ avg_over_time r : InstantVector Scalar + + +Γ ⊦ r : RangeVector Scalar +------------------------------------------ ✔ +Γ ⊦ sum_over_time r : InstantVector Scalar + + +Γ ⊦ q : Scalar // must be in range of [0; 1] +Γ ⊦ r : RangeVector +------------------------------------------------- ✔ +Γ ⊦ quantile_over_time q r : InstantVector Scalar + + +// Returns elements of `u` whose label instance doesn't occur in `v` +Γ ⊦ u : InstantVector a +Γ ⊦ v : InstantVector b +-------------------------------- ✔ +Γ ⊦ unless u v : InstantVector a + + +// meta-level abbreviation +Γ ⊦ a : InstantVector Scalar +Γ ⊦ s : Scalar +------------------------------------------------------------ ✔ +Γ ⊦ lte_instant_vector_scalar a s : InstantVector Scalar + lte_instant_vector_scalar a s ≡ filter (\v -> v <= s) a // same rule holds for other binary relations + + +// meta-level abbreviation +Γ ⊦ v : InstantVector Scalar +Γ ⊦ s : Scalar +------------------------------------ ✗ +Γ ⊦ v <= bool s : InstantVector Bool +v <= bool s ≡ (\x -> x <= s) v + + +// meta-level definition (define via map) +Γ ⊦ v : InstantVector Scalar +Γ ⊦ s : Scalar +-------------------------------------------------------- ✔ +Γ ⊦ add_instant_vector_scalar v s : InstantVector Scalar + + +// meta-level definition (define via map) +Γ ⊦ v : InstantVector Scalar +Γ ⊦ s : Scalar +-------------------------------------------------------- ✔ +Γ ⊦ sub_instant_vector_scalar v s : InstantVector Scalar + + +// meta-level definition (define via map) +Γ ⊦ v : InstantVector Scalar +Γ ⊦ s : Scalar +---------------------------------------------------- ✔ +Γ ⊦ mul_instant_vector_scalar : InstantVector Scalar + + +// meta-level definition (define via map) +Γ ⊦ v : InstantVector Scalar +Γ ⊦ s : Scalar +-------------------------------------------------------- ✔ +Γ ⊦ div_instant_vector_scalar v s : InstantVector Scalar + + +// meta-level definition (define via map) +Γ ⊦ v : InstantVector Bool +----------------------------------------------------- ✔ +Γ ⊦ instant_vector_to_scalar v : InstantVector Scalar + + +Γ ⊦ q : Scalar +Γ ⊦ v : InstantVector Scalar +-------------------------------------------- ✔ +Γ ⊦ quantile_by q v l̄ : InstantVector Scalar + +Γ ctx +------------------ ✔ +Γ ⊦ metrics : Text diff --git a/bench/cardano-timeseries-io/examples/query1.txt b/bench/cardano-timeseries-io/examples/query1.txt new file mode 100644 index 00000000000..6d9ab563986 --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query1.txt @@ -0,0 +1,7 @@ +let lagBlocks = 42 in +let lagSeconds = 42 in +let maxBlock = max ((blockMetric now) {"environment" = "${env}"}) in +let maxSlot = max ((slotMetric now) {"environment" = "${env}"}) in +let block = map (\x -> abs (maxBlock - x) > lagBlocks) ((blockMetric now) {"environment" = "${env}"}) in +let slot = map (\x -> abs (maxSlot - x) < lagSeconds) ((slotMetric now) {"environment" = "${env}"}) in +filter (\x -> fst x && !(snd x)) (join block slot) diff --git a/bench/cardano-timeseries-io/examples/query10.txt b/bench/cardano-timeseries-io/examples/query10.txt new file mode 100644 index 00000000000..b47af4df90d --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query10.txt @@ -0,0 +1,9 @@ +unless + ( + filter (\x -> x) + (map + (\x -> x < 350) + (sum_over_time (\t -> map (\x -> to_scalar (x != 0)) (cardano_node_metrics_blockNum_int t))[now-360m;now:1m]) + ) + ) + (cardano_node_metrics_blockNum_int now) diff --git a/bench/cardano-timeseries-io/examples/query11.txt b/bench/cardano-timeseries-io/examples/query11.txt new file mode 100644 index 00000000000..c4f24b00777 --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query11.txt @@ -0,0 +1,4 @@ +let chainDensityVeryLow = 42 in +100 * quantile_by ("environment") 0.2 (20 * cardano_node_metrics_density_real now) +< +chainDensityVeryLow diff --git a/bench/cardano-timeseries-io/examples/query12.txt b/bench/cardano-timeseries-io/examples/query12.txt new file mode 100644 index 00000000000..99395ddc614 --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query12.txt @@ -0,0 +1,6 @@ +let chainDensityLow = 42 in +100 * quantile_by ("environment") + 0.2 + (20 * (cardano_node_metrics_density_real now) {"environment" != "preview"}) +< +chainDensityLow diff --git a/bench/cardano-timeseries-io/examples/query2.txt b/bench/cardano-timeseries-io/examples/query2.txt new file mode 100644 index 00000000000..d51be02db18 --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query2.txt @@ -0,0 +1,2 @@ +let periodNotice = 42 in +kesPeriodsRemaining now <= periodNotice diff --git a/bench/cardano-timeseries-io/examples/query3.txt b/bench/cardano-timeseries-io/examples/query3.txt new file mode 100644 index 00000000000..97af2df70f9 --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query3.txt @@ -0,0 +1 @@ +increase cardano_node_metrics_Forge_forged_int[now - 24h; now] == 0 diff --git a/bench/cardano-timeseries-io/examples/query4.txt b/bench/cardano-timeseries-io/examples/query4.txt new file mode 100644 index 00000000000..d4e227c499d --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query4.txt @@ -0,0 +1 @@ +rate cardano_node_metrics_slotsMissedNum_int[now - 5m; now] > 0.5 diff --git a/bench/cardano-timeseries-io/examples/query5.txt b/bench/cardano-timeseries-io/examples/query5.txt new file mode 100644 index 00000000000..88144b68140 --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query5.txt @@ -0,0 +1 @@ +avg_over_time netdata_statsd_cardano_node_ping_latency_ms_gauge_value_average[now - 5m; now] > 500 diff --git a/bench/cardano-timeseries-io/examples/query6.txt b/bench/cardano-timeseries-io/examples/query6.txt new file mode 100644 index 00000000000..655b15f35ed --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query6.txt @@ -0,0 +1 @@ +avg (quantile_over_time 0.95 cardano_node_metrics_blockadoption_forgeDelay_real[now - 6h; now]) >= 4.5 diff --git a/bench/cardano-timeseries-io/examples/query7.txt b/bench/cardano-timeseries-io/examples/query7.txt new file mode 100644 index 00000000000..cc25e772207 --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query7.txt @@ -0,0 +1,2 @@ +let highBlockUtilization = 42 in +100.0 * avg (avg_over_time cardano_node_metrics_blockfetchclient_blocksize[now - 6h; now] / 90112) > highBlockUtilization diff --git a/bench/cardano-timeseries-io/examples/query8.txt b/bench/cardano-timeseries-io/examples/query8.txt new file mode 100644 index 00000000000..be240120410 --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query8.txt @@ -0,0 +1 @@ +cardano_node_metrics_blockfetchclient_blockdelay_cdfFive now < 0.9 diff --git a/bench/cardano-timeseries-io/examples/query9.txt b/bench/cardano-timeseries-io/examples/query9.txt new file mode 100644 index 00000000000..5adc53374d6 --- /dev/null +++ b/bench/cardano-timeseries-io/examples/query9.txt @@ -0,0 +1,6 @@ +map (\x -> round x) + (increase + (\t -> map (\x -> to_scalar (x < 300)) (to_scalar t - cardano_node_metrics_nodeStartTime_int t))[now-1h;now:1m] + ) +> +1 diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/API.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/API.hs new file mode 100644 index 00000000000..f32000f9bc5 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/API.hs @@ -0,0 +1,50 @@ +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE OverloadedRecordDot #-} +module Cardano.Timeseries.API + ( ExecutionError(..) + , execute + , module Export + ) where + +import Cardano.Timeseries.AsText as Export (AsText (..), showT) +import Cardano.Timeseries.Domain.Types as Export (MetricIdentifier, Timestamp) +import Cardano.Timeseries.Elab as Export (elab, initialSt) +import Cardano.Timeseries.Elab.Expr.Parser as Export (Parser, expr) +import Cardano.Timeseries.Interp as Export (interp) +import Cardano.Timeseries.Interp.Config as Export (Config (..)) +import Cardano.Timeseries.Interp.Types as Export (InterpError (..), InterpM) +import Cardano.Timeseries.Interp.Value as Export (Value (..)) +import Cardano.Timeseries.Store as Export (Store (..)) +import Cardano.Timeseries.Store.Flat as Export (Flat) +import Cardano.Timeseries.Store.Flat.Parser as Export (double, point) +import Cardano.Timeseries.Store.Tree as Export (Tree, fromFlat) + +import Control.Monad.Except (runExceptT) +import Control.Monad.State.Strict (evalState) +import Data.Bifunctor (first) +import Data.Text (Text) +import qualified Data.Text as Text +import Text.Megaparsec hiding (count) +import Text.Megaparsec.Char (space) + +data ExecutionError where + ParsingErrorWhileExecuting :: {message :: Text} -> ExecutionError + ElabErrorWhileExecuting :: {message :: Text} -> ExecutionError + InterpErrorWhileExecuting :: {message :: Text} -> ExecutionError deriving (Show) + +instance AsText ExecutionError where + asText ParsingErrorWhileExecuting{message} = "While executing, parsing error: " <> message + asText ElabErrorWhileExecuting{message} = "While executing, elaboration error: " <> message + asText InterpErrorWhileExecuting{message} = "While executing, interpretation error: " <> message + +-- | A pure interface to the composite of parsing, elaboration and interpretation of timeseries queries. +execute :: Store s Double => s -> Config -> Timestamp -> Text -> Either ExecutionError Value +execute store interpCfg now stringQuery = do + surfaceQuery <- first (ParsingErrorWhileExecuting . Text.pack . errorBundlePretty) $ + parse (expr <* space <* eof) "input" stringQuery + query <- first ElabErrorWhileExecuting $ + evalState (runExceptT (elab surfaceQuery)) initialSt + first (InterpErrorWhileExecuting . (.message)) $ + evalState (runExceptT $ interp interpCfg store mempty query now) 0 diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/AsText.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/AsText.hs new file mode 100644 index 00000000000..e61bb155c53 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/AsText.hs @@ -0,0 +1,10 @@ +module Cardano.Timeseries.AsText(AsText(..), showT) where + +import Cardano.Logging (showT) + +import Data.Text (Text) + +-- | For the purpose of pretty-printing. +-- Result may include linebreaks. +class AsText a where + asText :: a -> Text diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Component.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Component.hs new file mode 100644 index 00000000000..0ac0ef4792f --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Component.hs @@ -0,0 +1,138 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Use newtype instead of data" #-} +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +module Cardano.Timeseries.Component( + TimeseriesConfig(..) + , TimeseriesHandle + , QueryId + , create + , modifyConfig + , readConfig + , writeConfig + , insert + , execute + , prune) where +import Cardano.Logging (Trace, threadLabelMe, traceWith) +import Cardano.Timeseries.API hiding (execute, insert) +import qualified Cardano.Timeseries.API as API +import Cardano.Timeseries.Component.Trace +import Cardano.Timeseries.Component.Types +import Cardano.Timeseries.Domain.Instant +import qualified Cardano.Timeseries.Interp.Config as Interp +import Cardano.Timeseries.Util (diag, getTimeMs) + +import Prelude hiding (Foldable (..)) + +import Control.Arrow (second) +import Control.Concurrent (MVar, newEmptyMVar, putMVar, takeMVar, threadDelay) +import Control.Concurrent.Async (async, link, race_) +import Control.Concurrent.STM (TVar, modifyTVar', newTVarIO, readTVar, readTVarIO, + stateTVar) +import Control.Monad (forever) +import Control.Monad.STM (atomically) +import Data.Foldable (Foldable (..)) +import Data.Maybe (fromMaybe) +import qualified Data.Set as Set +import Data.Text (Text) + +-- | Not exported. The user gets the default if `create`-d with a `Nothing` +defaultTimeseriesInterpConfig :: Interp.Config +defaultTimeseriesInterpConfig = Interp.Config + (15 * 1000) -- 15 s + +-- | Not exported. The user gets the default if `create`-d with a `Nothing` +defaultTimeseriesConfig :: TimeseriesConfig +defaultTimeseriesConfig = TimeseriesConfig + (1 * 24 * 60 * 60 * 1000) -- 1 day in ms + (Just (1 * 60 * 60)) -- 1 hour in s + defaultTimeseriesInterpConfig + +-- | The constructor and projections are not exported. Use the API methods below for working with timeseries. +data TimeseriesHandle where + TimeseriesHandle :: Store s Double => + { config :: TVar TimeseriesConfig -- ^ Dynamically adjustable configuration. + , store :: TVar s -- ^ A timeseries store. + , reconfigured :: MVar () -- ^ A synchronisation primitive used for (waiting for)/signaling a reconfiguration. + , tracer :: Trace IO TimeseriesTrace -- ^ A tracer supplied on creation of the handle. + , nextQueryId :: TVar QueryId -- ^ A mutable integer for assigning a unique serial identifier to every executed query. + } -> TimeseriesHandle + +-- Create an opaque "handle" for a timeseries store, given an optional configuration. +-- Also spawns a "pruner" thread (if specified in the config) that periodically prunes the store of expired entries. +create :: forall s. Store s Double => Trace IO TimeseriesTrace -> Maybe TimeseriesConfig -> IO TimeseriesHandle +create tr mbCfg = do + cfg <- newTVarIO (fromMaybe defaultTimeseriesConfig mbCfg) + st <- newTVarIO (new @s) + qid <- newTVarIO 0 + reconf <- newEmptyMVar + let handle = TimeseriesHandle cfg st reconf tr qid + async (runPruner handle) >>= link + traceWith tr (TimeseriesTraceCreate mbCfg) + pure handle + where + runPruner :: TimeseriesHandle -> IO () + runPruner handle = threadLabelMe "timeseries-pruner-thread" >> do + forever $ do + cfg <- readTVarIO handle.config + case cfg.pruningPeriodSec of + Nothing -> + -- If the current configuration doesn't specify a pruning period, we block + -- the thread until a reconfiguration happens. + takeMVar handle.reconfigured + Just period -> do + prune handle + -- Wait for the given period or wake up on a reconfiguration. + race_ + (threadDelay (fromIntegral period * 1_000_000)) + (takeMVar handle.reconfigured) + +-- | Reconfigure the store. The new parameters are applied immediately. +-- Wakes up the pruner thread as well. +-- If the supplied config is empty, reconfigures back to the default config. +modifyConfig :: TimeseriesHandle -> (TimeseriesConfig -> Maybe TimeseriesConfig) -> IO () +modifyConfig handle cfg = do + newCfg <- atomically $ stateTVar handle.config (second (fromMaybe defaultTimeseriesConfig) . diag . cfg) + putMVar handle.reconfigured () + traceWith handle.tracer (TimeseriesTraceReconfigure newCfg) + +-- | Read a snapshot of the configuration. +readConfig :: TimeseriesHandle -> IO TimeseriesConfig +readConfig handle = readTVarIO handle.config + +-- | A specialised version of `modifyConfig` where the value of the new config doesn't depend on the old one. +writeConfig :: TimeseriesHandle -> Maybe TimeseriesConfig -> IO () +writeConfig handle k = modifyConfig handle (const k) + +-- | Insert a batch on metric data into the store at the given timestamp. +insert :: TimeseriesHandle -> Text -> Text -> Timestamp -> [(MetricIdentifier, Double)] -> IO () +insert TimeseriesHandle{..} originKey originValue t batch = do + atomically $ modifyTVar' store $ \st -> foldl' f st batch + traceWith tracer (TimeseriesTraceInsert originKey originValue t batch) + where + f st (k, v) = API.insert st k (Instant (Set.singleton (originKey, originValue)) t v) + +-- | Execute a query on the store at the given timestamp (ms). +execute :: TimeseriesHandle -> Timestamp -> Text -> IO (Either ExecutionError Value) +execute TimeseriesHandle{..} at stringQuery = do + (theCfg, theStore) <- atomically $ (,) <$> readTVar config <*> readTVar store + queryId <- atomically $ stateTVar nextQueryId (second (+ 1) . diag) + traceWith tracer (TimeseriesTraceIssueExecute queryId stringQuery) + let result = API.execute theStore theCfg.interpCfg (fromIntegral at) stringQuery + traceWith tracer (TimeseriesTraceYieldExecute queryId result) + pure result + +-- | Prune the store of the entries past the configured retention period (relative to "now"). +-- The pruner thread uses that function internally, but one can still invoke the pruning manually at will. +prune :: TimeseriesHandle -> IO () +prune TimeseriesHandle{..} = do + t <- getTimeMs + theCfg <- readTVarIO config + atomically $ modifyTVar' store (\s -> API.truncate s (fromIntegral t - theCfg.retentionMillis)) + traceWith tracer (TimeseriesTracePrune theCfg.retentionMillis) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Component/Trace.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Component/Trace.hs new file mode 100644 index 00000000000..3ddfbfc94e8 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Component/Trace.hs @@ -0,0 +1,91 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Cardano.Timeseries.Component.Trace(TimeseriesTrace(..)) where + +import Cardano.Logging (LogFormatting (..), SeverityS (..)) +import Cardano.Logging.Types (MetaTrace (..), Namespace (..)) +import Cardano.Timeseries.API +import Cardano.Timeseries.Component.Types + +import Data.Aeson (toJSON) +import Data.Aeson.Key (fromText) +import Data.Aeson.KeyMap (singleton) +import Data.Aeson.Types ((.=)) +import Data.Text (Text) +import Data.Word (Word64) + +data TimeseriesTrace = TimeseriesTraceCreate (Maybe TimeseriesConfig) + | TimeseriesTraceReconfigure (Maybe TimeseriesConfig) + | TimeseriesTraceInsert + Text -- ^ Origin key + Text -- ^ Origin value + Timestamp + [(MetricIdentifier, Double)] -- ^ Payload + | TimeseriesTraceIssueExecute QueryId Text + | TimeseriesTraceYieldExecute QueryId (Either ExecutionError Value) + -- COMMENT: (@russoul) shall we count the number of pruned entries? + | TimeseriesTracePrune + Word64 -- ^ retention (ms) + deriving (Show) + +instance LogFormatting TimeseriesTrace where + forMachine _ (TimeseriesTraceCreate cfg) = + singleton "cfg" (toJSON cfg) + forMachine _ (TimeseriesTraceReconfigure cfg) = + singleton "cfg" (toJSON cfg) + forMachine _ (TimeseriesTraceInsert originKey originValue t batch) = mconcat + [ + fromText originKey .= originValue + , + "timestamp" .= t + , + "batch" .= batch + ] + forMachine _ (TimeseriesTraceIssueExecute queryId queryText) = mconcat + [ + "query_id" .= queryId + , + "query_text" .= queryText + ] + forMachine _ (TimeseriesTraceYieldExecute queryId result) = mconcat + [ + "query_id" .= queryId + , + "query_result" .= either asText showT result + ] + forMachine _ (TimeseriesTracePrune retMs) = + singleton "retention_millis" (toJSON retMs) + +instance MetaTrace TimeseriesTrace where + allNamespaces = + [ + Namespace [] ["Timeseries", "Create"] + , Namespace [] ["Timeseries", "Reconfigure"] + , Namespace [] ["Timeseries", "Insert"] + , Namespace [] ["Timeseries", "IssueExecute"] + , Namespace [] ["Timeseries", "YieldExecute"] + , Namespace [] ["Timeseries", "Prune"] + ] + + namespaceFor TimeseriesTraceCreate{} = Namespace [] ["Timeseries", "Create"] + namespaceFor TimeseriesTraceReconfigure{} = Namespace [] ["Timeseries", "Reconfigure"] + namespaceFor TimeseriesTraceInsert{} = Namespace [] ["Timeseries", "Insert"] + namespaceFor TimeseriesTraceIssueExecute{} = Namespace [] ["Timeseries", "IssueExecute"] + namespaceFor TimeseriesTraceYieldExecute{} = Namespace [] ["Timeseries", "YieldExecute"] + namespaceFor TimeseriesTracePrune{} = Namespace [] ["Timeseries", "Prune"] + + severityFor (Namespace [] ["Timeseries", "Create"]) _ = Just Info + severityFor (Namespace [] ["Timeseries", "Reconfigure"]) _ = Just Info + severityFor (Namespace [] ["Timeseries", "Insert"]) _ = Just Debug -- That one clogs up the traces, hence lower severity + severityFor (Namespace [] ["Timeseries", "IssueExecute"]) _ = Just Info + severityFor (Namespace [] ["Timeseries", "YieldExecute"]) _ = Just Info + severityFor (Namespace [] ["Timeseries", "Prune"]) _ = Just Info + severityFor _ _ = Nothing + + documentFor (Namespace [] ["Timeseries", "Create"]) = Just "A timeseries handle has been created." + documentFor (Namespace [] ["Timeseries", "Reconfigure"]) = Just "The timeseries handle has been reconfigured." + documentFor (Namespace [] ["Timeseries", "Insert"]) = Just "A batch of metrics from one node has been inserted to the store." + documentFor (Namespace [] ["Timeseries", "IssueExecute"]) = Just "The timeseries query has been issued." + documentFor (Namespace [] ["Timeseries", "YieldExecute"]) = Just "The timeseries query has yielded a result." + documentFor (Namespace [] ["Timeseries", "Prune"]) = Just "The timeseries store has been pruned." + documentFor _ = Nothing diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Component/Types.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Component/Types.hs new file mode 100644 index 00000000000..e650d2601bb --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Component/Types.hs @@ -0,0 +1,21 @@ +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} + +module Cardano.Timeseries.Component.Types(QueryId, TimeseriesConfig(..)) where +import qualified Cardano.Timeseries.Interp.Config as Interp + +import Data.Aeson (ToJSON) +import Data.Word (Word64) +import GHC.Generics + +type QueryId = Word64 + +data TimeseriesConfig = TimeseriesConfig { + -- | How long the store entries are retained for (ms). + retentionMillis :: Word64 + -- | How often the pruner thread shall prune the store (sec), if enabled. + , pruningPeriodSec :: Maybe Word64 + -- | Parameters of timeseries query interpretation. + , interpCfg :: Interp.Config +} deriving (Show, Generic, ToJSON) + diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Identifier.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Identifier.hs new file mode 100644 index 00000000000..840e5c69ef5 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Identifier.hs @@ -0,0 +1,14 @@ +module Cardano.Timeseries.Domain.Identifier(Identifier(..)) where + +import Cardano.Timeseries.AsText + +import Data.Text (Text, cons) + +-- | Identifiers come in two sorts: Userspace and Machine-generated. +-- | The first kind comes from user-typed expressions. +-- | The second kind is used for automatic code-generation for hygienic scoping (i.e. to avoid unintentional variable capture) +data Identifier = User Text | Machine Int deriving (Show, Ord, Eq) + +instance AsText Identifier where + asText (User x) = x + asText (Machine i) = '$' `cons` showT i diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Instant.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Instant.hs new file mode 100644 index 00000000000..5c2f1d7fb90 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Instant.hs @@ -0,0 +1,43 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE FlexibleInstances #-} + +module Cardano.Timeseries.Domain.Instant(Instant(..), InstantVector, mostRecent, share, toVector) where + +import Cardano.Timeseries.AsText +import Cardano.Timeseries.Domain.Types (SeriesIdentifier, Timestamp) + +import Control.DeepSeq (NFData) +import qualified Data.Set as Set +import Data.Text as Text (pack, unlines) +import Data.Vector +import GHC.Generics (Generic) + +-- | One datapoint in a series. +data Instant a = Instant { + labels :: SeriesIdentifier, + timestamp :: Timestamp, + value :: a +} deriving (Show, Eq, Functor, Foldable, Traversable, Generic) + +instance NFData a => NFData (Instant a) + +-- | Do the instant vectors share a series? +share :: Instant a -> Instant b -> Bool +share a b = labels a == labels b + +-- | Datapoints from different series. The vector must not contain datapoints sharing a series. +type InstantVector a = [Instant a] + +mostRecent :: Instant a -> Instant a -> Instant a +mostRecent u v = if timestamp u < timestamp v then v else u + +toVector :: InstantVector Double -> Vector Double +toVector = fromList . fmap value + +instance Show a => AsText (Instant a) where + asText (Instant ls t v) = + pack (show (Set.toList ls)) <> " " <> pack (show t) <> " " <> pack (show v) + +instance Show a => AsText (InstantVector a) where + asText = Text.unlines . fmap asText diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Interval.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Interval.hs new file mode 100644 index 00000000000..70916400565 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Interval.hs @@ -0,0 +1,12 @@ +module Cardano.Timeseries.Domain.Interval(Interval(..), duration) where + +import Cardano.Timeseries.Domain.Types (Timestamp) + +-- | A time interval. Assumption: `start` ≤ `end` +data Interval = Interval { + start :: Timestamp, + end :: Timestamp +} deriving (Show, Eq) + +duration :: Interval -> Double +duration (Interval s e) = fromIntegral (e - s) / 2 diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Timeseries.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Timeseries.hs new file mode 100644 index 00000000000..b7db5ad70b2 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Timeseries.hs @@ -0,0 +1,115 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE RecordWildCards #-} + +module Cardano.Timeseries.Domain.Timeseries(Timeseries(..), TimeseriesVector, + transpose, toVector, oldest, newest, eachOldest, eachNewest, superseries) where + +import Cardano.Timeseries.AsText +import Cardano.Timeseries.Domain.Instant (Instant (Instant), InstantVector) +import qualified Cardano.Timeseries.Domain.Instant as Instant +import Cardano.Timeseries.Domain.Types + +import Control.DeepSeq (NFData) +import Data.Function (on) +import Data.List (find, maximumBy, minimumBy) +import Data.Set +import qualified Data.Set as Set +import qualified Data.Text as Text +import Data.Vector (Vector) +import qualified Data.Vector as Vector +import GHC.Generics (Generic) + +-- | A collection of datapoints sharing a series. +data Timeseries a = Timeseries { + labels :: SeriesIdentifier, + dat :: [(Timestamp, a)] +} deriving (Show, Functor, Foldable, Traversable, Generic) + +instance NFData a => NFData (Timeseries a) + +oldest :: Timeseries a -> Maybe (Instant a) +oldest Timeseries{..} | Prelude.null dat = Nothing +oldest Timeseries{..} = + let (t, x) = minimumBy (compare `on` fst) dat in + Just (Instant labels t x) + +newest :: Timeseries a -> Maybe (Instant a) +newest Timeseries{..} | Prelude.null dat = Nothing +newest Timeseries{..} = + let (t, x) = maximumBy (compare `on` fst) dat in + Just (Instant labels t x) + +-- | Every two elements in the list must have distinct series identifiers (set of labels), +-- | i.e. the series in the list must be distinct. +type TimeseriesVector a = [Timeseries a] + +eachOldest :: TimeseriesVector a -> Maybe [Instant a] +eachOldest = traverse oldest + +eachNewest :: TimeseriesVector a -> Maybe [Instant a] +eachNewest = traverse newest + +-- | Given a list of range vectors, forms up a timeseries vector. +-- | This operation is, in some sense, transposition: +-- | +-- | ⎴ ⎴ ⎴ ⎴ +-- | series1: ... ◯ ◯ ... +-- | series2: ... ◯ ◯ ... +-- | series3: ... ◯ ◯ ◯ ... +-- | ... ... +-- | ⎵ ⎵ ⎵ ⎵ +-- | -------------------------------> t +-- | t₀ t₁ t₂ t₃ +-- | +-- | =====> +-- | +-- | +-- | +-- | series1: [ ... ◯ ◯ ... ] +-- | series2: [ ... ◯ ◯ ... ] +-- | series3: [ ... ◯ ◯ ◯ ... ] +-- | ... ... +-- | +-- | ----------------------------------------> t +-- t₀ t₁ t₂ t₃ +transpose :: [InstantVector a] -> TimeseriesVector a +transpose instants = + Set.foldl' (\vector ls -> form ls instants : vector) [] (setOfLabels instants) where + + -- | Given a set of labels (identifying a series) form up a series from a list of instant vectors. + form :: SeriesIdentifier -> [InstantVector a] -> Timeseries a + form ls insts_ = Timeseries ls (formInt insts_) where + -- | Extract the data pertaining to the series (identified by the given `SeriesIdentifier`) from the list of + -- | ranges vectors. + formInt :: [InstantVector a] -> [(Timestamp, a)] + formInt [] = [] + formInt (inst : insts) = + case find (\i -> Instant.labels i == ls) inst of + Just i -> (Instant.timestamp i, Instant.value i) : formInt insts + Nothing -> formInt insts + + setOfLabels' :: InstantVector a -> Set SeriesIdentifier + setOfLabels' [] = Set.empty + setOfLabels' (i : is) = Set.insert (Instant.labels i) (setOfLabels' is) + + setOfLabels :: [InstantVector a] -> Set SeriesIdentifier + setOfLabels [] = Set.empty + setOfLabels (v : vs) = setOfLabels' v `Set.union` setOfLabels vs + +toVector :: Timeseries Double -> Vector Double +toVector = Vector.fromList . fmap snd . dat + +-- Widen the series by the given set of labels. +superseries :: Set Label -> SeriesIdentifier -> SeriesIdentifier +superseries ls = Set.filter (\(k, _) -> k `elem` ls) + +instance Show a => AsText (Timeseries a) where + asText (Timeseries ls ps) = + showT (Set.toList ls) + <> "\n" + <> Text.unlines (fmap (\(t, v) -> showT t <> " " <> showT v) ps) + +instance Show a => AsText (TimeseriesVector a) where + asText = Text.unlines . fmap asText diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Types.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Types.hs new file mode 100644 index 00000000000..edf61667fee --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Domain/Types.hs @@ -0,0 +1,21 @@ +module Cardano.Timeseries.Domain.Types(MetricIdentifier, Label, Labelled, Timestamp, SeriesIdentifier) where + +import Prelude hiding (length) + +import Data.Set (Set) +import Data.Text (Text) +import Data.Word (Word64) + +-- | Each series in the (metric) store can be identified by a metric name. +type MetricIdentifier = Text + +type Label = Text + +-- | Key-value pair of a label and its value. +type Labelled a = (Label, a) + +-- | Series is identified by a set of labels. Hence the name. +type SeriesIdentifier = Set (Labelled Text) + +-- | Milliseconds since epoch. +type Timestamp = Word64 diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab.hs new file mode 100644 index 00000000000..a710202888a --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab.hs @@ -0,0 +1,894 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE ViewPatterns #-} + +module Cardano.Timeseries.Elab(initialSt, St(..), ElabM, elab) where +import Cardano.Timeseries.AsText +import Cardano.Timeseries.Domain.Identifier (Identifier) +import Cardano.Timeseries.Elab.Expr (Loc, getLoc) +import qualified Cardano.Timeseries.Elab.Expr as Surface +import Cardano.Timeseries.Elab.Resolve +import Cardano.Timeseries.Elab.Typing (Binding (..), Context, Def (..), Defs, + Ty (Bool, Duration, Fun, Hole, InstantVector, RangeVector, Scalar, Timestamp), + TyPrec (Loose), instantiateExpr, prettyTy) +import qualified Cardano.Timeseries.Elab.Typing as Ty +import qualified Cardano.Timeseries.Elab.Typing as Types +import Cardano.Timeseries.Elab.Unify (UnificationProblem (..), UnifyM) +import qualified Cardano.Timeseries.Elab.Unify as Unify +import Cardano.Timeseries.Interp.BinaryArithmeticOp +import qualified Cardano.Timeseries.Interp.BinaryArithmeticOp as BinaryArithmeticOp +import Cardano.Timeseries.Interp.BinaryRelation (BinaryRelation) +import qualified Cardano.Timeseries.Interp.BinaryRelation as BinaryRelation +import Cardano.Timeseries.Interp.Expr (HoleIdentifier) +import qualified Cardano.Timeseries.Interp.Expr as Semantic + +import Control.Monad (forM_) +import Control.Monad.Except (ExceptT, liftEither, runExceptT, throwError) +import Control.Monad.State.Strict (State, get, modify, put, runState) +import Data.Foldable as Foldable (toList) +import Data.List (find) +import qualified Data.Map.Strict as Map +import Data.Sequence as Seq (Seq (..), fromList, singleton, (><), (|>)) +import Data.Text (Text, pack) +import qualified Data.Text as Text + + +-- | Γ ⊦ s ~> ?x : A +data GeneralElabProblem = GeneralElabProblem { + gamma :: Context, + surface :: Surface.Expr, + hole :: HoleIdentifier, + holeTy :: Ty +} deriving (Show) + +instance AsText GeneralElabProblem where + asText (GeneralElabProblem gam sur _ holeTy) = + asText gam + <> " ⊦ " + <> prettyTy Loose holeTy + <> "\n @ " + <> asText (getLoc sur) + +evalGeneralElabProblem :: Defs -> GeneralElabProblem -> GeneralElabProblem +evalGeneralElabProblem defs (GeneralElabProblem gam tm hole holeTy) = + GeneralElabProblem (resolveContext defs gam) tm hole (resolveTy defs holeTy) + +-- | Γ ⊦ ((t : T) R (t : T)) ~> ? : T +data BinaryRelationElabProblem = BinaryRelationElabProblem { + gamma :: Context, + loc :: Loc, + lhs :: Semantic.Expr, + lhsTy :: Ty, + rel :: BinaryRelation.BinaryRelation, + rhs :: Semantic.Expr, + rhsTy :: Ty, + hole :: HoleIdentifier, + holeTy :: Ty +} deriving (Show) + +prettyBinaryRelationElabProblem :: BinaryRelationElabProblem -> Text +prettyBinaryRelationElabProblem (BinaryRelationElabProblem gam loc _ lhsTy rel _ rhsTy _ holeTy) = + asText gam + <> " ⊦ " + <> prettyTy Loose lhsTy + <> " " + <> asText rel + <> " " + <> prettyTy Loose rhsTy + <> " : " + <> prettyTy Loose holeTy + <> "\n @ " + <> asText loc + +evalBinaryRelationElabProblem :: Defs -> BinaryRelationElabProblem -> BinaryRelationElabProblem +evalBinaryRelationElabProblem defs (BinaryRelationElabProblem gam loc lhs lhsTy rel rhs rhsTy hole holeTy) = + BinaryRelationElabProblem + (resolveContext defs gam) + loc + lhs + (resolveTy defs lhsTy) + rel + rhs + (resolveTy defs rhsTy) + hole + (resolveTy defs holeTy) + +-- | Γ ⊦ (t R t) ~> ? : t +data BinaryArithmeticOpElabProblem = BinaryArithmeticOpElabProblem { + gamma :: Context, + loc :: Loc, + lhs :: Semantic.Expr, + lhsTy :: Ty, + op :: BinaryArithmeticOp.BinaryArithmeticOp, + rhs :: Semantic.Expr, + rhsTy :: Ty, + hole :: HoleIdentifier, + holeTy :: Ty +} deriving (Show) + +prettyBinaryArithmeticOpElabProblem :: BinaryArithmeticOpElabProblem -> Text +prettyBinaryArithmeticOpElabProblem (BinaryArithmeticOpElabProblem gam loc _ lhsTy op _ rhsTy _ holeTy) = + asText gam + <> " ⊦ " + <> prettyTy Loose lhsTy + <> " " + <> asText op + <> " " + <> prettyTy Loose rhsTy + <> " : " + <> prettyTy Loose holeTy + <> "\n @ " + <> asText loc + +evalBinaryArithmethicOpElabProblem :: Defs -> BinaryArithmeticOpElabProblem -> BinaryArithmeticOpElabProblem +evalBinaryArithmethicOpElabProblem defs (BinaryArithmeticOpElabProblem gam loc lhs lhsTy op rhs rhsTy hole holeTy) = + BinaryArithmeticOpElabProblem + (resolveContext defs gam) + loc + lhs + (resolveTy defs lhsTy) + op + rhs + (resolveTy defs rhsTy) + hole + (resolveTy defs holeTy) + +-- | Γ ⊦ to_scalar (t : T) ~> ? +data ToScalarElabProblem = ToScalarElabProblem { + gamma :: Context, + loc :: Loc, + expr :: Semantic.Expr, + ty :: Ty, + hole :: HoleIdentifier +} deriving (Show) + +instance AsText ToScalarElabProblem where + asText (ToScalarElabProblem gam loc _ ty _) = + asText gam + <> " ⊦ to_scalar " + <> prettyTy Loose ty + <> "\n @ " + <> asText loc + +evalToScalarElabProblem :: Defs -> ToScalarElabProblem -> ToScalarElabProblem +evalToScalarElabProblem defs (ToScalarElabProblem gam loc expr exprTy hole) = + ToScalarElabProblem + (resolveContext defs gam) + loc + expr + (resolveTy defs exprTy) + hole + +data ElabProblem = General GeneralElabProblem + | BinaryRelation BinaryRelationElabProblem + | BinaryArithmeticOp BinaryArithmeticOpElabProblem + | ToScalar ToScalarElabProblem deriving (Show) + +instance AsText ElabProblem where + asText (General p) = asText p + asText (BinaryRelation p) = prettyBinaryRelationElabProblem p + asText (BinaryArithmeticOp p) = prettyBinaryArithmeticOpElabProblem p + asText (ToScalar p) = asText p + +evalElabProblem :: Defs -> ElabProblem -> ElabProblem +evalElabProblem defs (General p) = General (evalGeneralElabProblem defs p) +evalElabProblem defs (BinaryRelation p) = BinaryRelation (evalBinaryRelationElabProblem defs p) +evalElabProblem defs (BinaryArithmeticOp p) = BinaryArithmeticOp (evalBinaryArithmethicOpElabProblem defs p) +evalElabProblem defs (ToScalar p) = ToScalar (evalToScalarElabProblem defs p) + + +data St = St { + defs :: Defs, + nextHoleIdentifier :: HoleIdentifier +} + +initialSt :: St +initialSt = St mempty 0 + +updateDefs :: (Defs -> Defs) -> St -> St +updateDefs f (St ds x) = St (f ds) x + +getDefs :: St -> Defs +getDefs = defs + +setDefs :: Defs -> St -> St +setDefs v = updateDefs (const v) + +updateNextHoleIdentifier :: (HoleIdentifier -> HoleIdentifier) -> St -> St +updateNextHoleIdentifier f (St ds x) = St ds (f x) + +runUnifyM :: UnifyM a -> ElabM a +runUnifyM f = do + st <- get + let ds = getDefs st + let !(!r, Unify.St ds') = runState (runExceptT f) (Unify.St ds) + put (setDefs ds' st) + liftEither r + + +type ElabError = Text + +type ElabM a = ExceptT ElabError (State St) a + +freshHoleIdentifier :: ElabM HoleIdentifier +freshHoleIdentifier = do + x <- (.nextHoleIdentifier) <$> get + modify (updateNextHoleIdentifier (+ 1)) + pure x + +freshTyHole :: ElabM HoleIdentifier +freshTyHole = do + x <- freshHoleIdentifier + modify (updateDefs (Map.insert x TyHoleDecl)) + pure x + +freshExprHole :: Ty -> ElabM HoleIdentifier +freshExprHole typ = do + x <- freshHoleIdentifier + modify (updateDefs (Map.insert x (ExprHoleDecl typ))) + pure x + +mbBinaryRelation :: Surface.Expr -> Maybe (Loc, Surface.Expr, BinaryRelation.BinaryRelation, Surface.Expr) +mbBinaryRelation (Surface.Lte l a b) = Just (l, a, BinaryRelation.Lte, b) +mbBinaryRelation (Surface.Lt l a b) = Just (l, a, BinaryRelation.Lt, b) +mbBinaryRelation (Surface.Gte l a b) = Just (l, a, BinaryRelation.Gte, b) +mbBinaryRelation (Surface.Gt l a b) = Just (l, a, BinaryRelation.Gt, b) +mbBinaryRelation (Surface.Eq l a b) = Just (l, a, BinaryRelation.Eq, b) +mbBinaryRelation (Surface.NotEq l a b) = Just (l, a, BinaryRelation.NotEq, b) +mbBinaryRelation _ = Nothing + +mbBinaryArithmeticOp :: Surface.Expr -> Maybe (Loc, Surface.Expr, BinaryArithmeticOp.BinaryArithmeticOp, Surface.Expr) +mbBinaryArithmeticOp (Surface.Add l a b) = Just (l, a, BinaryArithmeticOp.Add, b) +mbBinaryArithmeticOp (Surface.Sub l a b) = Just (l, a, BinaryArithmeticOp.Sub, b) +mbBinaryArithmeticOp (Surface.Mul l a b) = Just (l, a, BinaryArithmeticOp.Mul, b) +mbBinaryArithmeticOp (Surface.Div l a b) = Just (l, a, BinaryArithmeticOp.Div, b) +mbBinaryArithmeticOp _ = Nothing + +checkFresh :: Context -> Identifier -> ElabM () +checkFresh ctx v = + forM_ (find (\b -> Types.identifier b == v) ctx) $ \found -> + throwError $ pack $ "Reused variable name: " <> show (Types.identifier found) + +-- | Γ ⊦ to_scalar (t : T) ~> ? +-- Assumes that `Ty` is normal w.r.t. hole substitution. +solveToScalarElabProblem :: Context + -> Loc + -> Semantic.Expr + -> Ty + -> HoleIdentifier + -> ElabM (Maybe ([UnificationProblem], [ElabProblem])) +solveToScalarElabProblem _ _ expr Scalar hole = do + modify $ updateDefs $ instantiateExpr hole expr + pure $ Just ([], []) +solveToScalarElabProblem _ _ expr Bool hole = do + modify $ updateDefs $ instantiateExpr hole (Semantic.BoolToScalar expr) + pure $ Just ([], []) +solveToScalarElabProblem _ _ expr Duration hole = do + modify $ updateDefs $ instantiateExpr hole (Semantic.DurationToScalar expr) + pure $ Just ([], []) +solveToScalarElabProblem _ _ expr Timestamp hole = do + modify $ updateDefs $ instantiateExpr hole (Semantic.TimestampToScalar expr) + pure $ Just ([], []) +solveToScalarElabProblem _ _ _ (Hole _) _ = pure Nothing +solveToScalarElabProblem _ loc _ badType _ = throwError $ + "to_scalar can't be applied to an expression of type " + <> prettyTy Loose badType + <> "\n @ " + <> asText loc + +-- | Σ Γ ⊦ InstantVector Scalar `rel` Scalar ~> ? : InstantVector Scalar +-- | Σ Γ ⊦ Scalar `rel` Scalar ~> ? : Bool +-- | Σ Γ ⊦ Bool `rel` Bool ~> ? : Bool +solveCanonicalBinaryRelationElabProblem :: Context + -> Loc + -> Semantic.Expr + -> Ty + -> BinaryRelation + -> Semantic.Expr + -> Ty + -> HoleIdentifier + -> Ty + -> ElabM (Maybe ([UnificationProblem], [ElabProblem])) +solveCanonicalBinaryRelationElabProblem _ _ lhs (InstantVector Scalar) rel rhs Scalar hole (InstantVector Scalar) = do + modify $ updateDefs $ + instantiateExpr hole + (BinaryRelation.embedInstantVectorScalar rel lhs rhs) + pure $ Just ([], []) +solveCanonicalBinaryRelationElabProblem _ _ lhs Scalar rel rhs Scalar hole Bool = do + modify $ updateDefs $ + instantiateExpr hole + (BinaryRelation.embedScalar rel lhs rhs) + pure $ Just ([], []) +solveCanonicalBinaryRelationElabProblem _ _ lhs Bool rel rhs Bool hole Bool = do + modify $ updateDefs $ + instantiateExpr hole + (BinaryRelation.embedBool rel lhs rhs) + pure $ Just ([], []) +solveCanonicalBinaryRelationElabProblem _ _ _ _ _ _ _ _ _ = pure Nothing + +solveNoncanonicalBinaryRelationElabProblem :: Context + -> Loc + -> Semantic.Expr + -> Ty + -> BinaryRelation + -> Semantic.Expr + -> Ty + -> HoleIdentifier + -> Ty + -> ElabM (Maybe ([UnificationProblem], [ElabProblem])) +solveNoncanonicalBinaryRelationElabProblem gam loc lhs (InstantVector Scalar) rel rhs Scalar hole typ = do + pure $ Just ([UnificationProblem loc typ (InstantVector Scalar)], + [BinaryRelation $ + BinaryRelationElabProblem gam loc lhs (InstantVector Scalar) + rel rhs Scalar hole (InstantVector Scalar)]) +solveNoncanonicalBinaryRelationElabProblem gam loc lhs Scalar rel rhs (InstantVector Scalar) hole typ = do + pure $ Just ([UnificationProblem loc typ (InstantVector Scalar)], + [BinaryRelation $ + BinaryRelationElabProblem gam loc rhs (InstantVector Scalar) + (BinaryRelation.swapInstantVectorScalar rel) lhs Scalar hole (InstantVector Scalar)]) +solveNoncanonicalBinaryRelationElabProblem gam loc lhs Scalar rel rhs Scalar hole typ = do + pure $ Just ([UnificationProblem loc typ Bool], + [BinaryRelation $ BinaryRelationElabProblem gam loc lhs Scalar rel rhs Scalar hole Bool]) +solveNoncanonicalBinaryRelationElabProblem gam loc lhs lhsTy rel rhs rhsTy hole Bool = do + pure $ Just ([UnificationProblem loc lhsTy Scalar, UnificationProblem loc rhsTy Scalar], + [BinaryRelation $ BinaryRelationElabProblem gam loc lhs Scalar rel rhs Scalar hole Bool]) +solveNoncanonicalBinaryRelationElabProblem gam loc lhs lhsTy rel rhs rhsTy hole typ | + lhsTy == Bool || rhsTy == Bool = do + pure $ Just ([UnificationProblem loc lhsTy Bool, UnificationProblem loc rhsTy Bool, UnificationProblem loc typ Bool], + [BinaryRelation $ BinaryRelationElabProblem gam loc lhs Bool rel rhs Bool hole Bool]) +solveNoncanonicalBinaryRelationElabProblem _ _ _ _ _ _ _ _ _ = pure Nothing + +-- | Σ Γ ⊦ (a : A) `rel` (b : B) ~> ?x : C +-- Assumes that all given `Ty` are normal w.r.t. hole substitution. +-- TODO: Check completeness +solveBinaryRelationElabProblem :: Context + -> Loc + -> Semantic.Expr + -> Ty + -> BinaryRelation + -> Semantic.Expr + -> Ty + -> HoleIdentifier + -> Ty + -> ElabM (Maybe ([UnificationProblem], [ElabProblem])) +solveBinaryRelationElabProblem gam loc lhs lhsTy rel rhs rhsTy hole holeTy = + solveCanonicalBinaryRelationElabProblem gam loc lhs lhsTy rel rhs rhsTy hole holeTy >>= \case + Nothing -> solveNoncanonicalBinaryRelationElabProblem gam loc lhs lhsTy rel rhs rhsTy hole holeTy + Just ok -> pure (Just ok) + +-- | Σ Γ ⊦ Timestamp + Duration ~> ? : Timestamp +-- | Σ Γ ⊦ Timestamp - Duration ~> ? : Timestamp +-- | Σ Γ ⊦ Duration + Duration ~> ? : Duration +-- | Σ Γ ⊦ Scalar `op` Scalar ~> ? : Scalar +-- | Σ Γ ⊦ InstantVector Scalar `op` Scalar ~> ? : InstantVector Scalar +solveCanonicalBinaryArithmeticOpElabProblem :: Context + -> Loc + -> Semantic.Expr + -> Ty + -> BinaryArithmeticOp + -> Semantic.Expr + -> Ty + -> HoleIdentifier + -> Ty + -> ElabM (Maybe ([UnificationProblem], [ElabProblem])) +solveCanonicalBinaryArithmeticOpElabProblem _ _ lhs Timestamp BinaryArithmeticOp.Add rhs Duration hole Timestamp = do + modify $ updateDefs $ + instantiateExpr hole + (Semantic.FastForward lhs rhs) + pure $ Just ([], []) +solveCanonicalBinaryArithmeticOpElabProblem _ _ lhs Duration BinaryArithmeticOp.Add rhs Duration hole Duration = do + modify $ updateDefs $ + instantiateExpr hole + (Semantic.AddDuration lhs rhs) + pure $ Just ([], []) +solveCanonicalBinaryArithmeticOpElabProblem _ _ lhs Timestamp BinaryArithmeticOp.Sub rhs Duration hole Timestamp = do + modify $ updateDefs $ + instantiateExpr hole + (Semantic.Rewind lhs rhs) + pure $ Just ([], []) +solveCanonicalBinaryArithmeticOpElabProblem _ _ lhs Scalar op rhs Scalar hole Scalar = do + modify $ updateDefs $ + instantiateExpr hole + (BinaryArithmeticOp.embedScalar op lhs rhs) + pure $ Just ([], []) +solveCanonicalBinaryArithmeticOpElabProblem _ _ lhs (InstantVector Scalar) + op rhs Scalar hole (InstantVector Scalar) = do + modify $ updateDefs $ + instantiateExpr hole + (BinaryArithmeticOp.embedInstantVectorScalar op lhs rhs) + pure $ Just ([], []) +solveCanonicalBinaryArithmeticOpElabProblem _ _ _ _ _ _ _ _ _ = pure Nothing + +solveNoncanonicalBinaryArithmeticOpElabProblem :: + Context + -> Loc + -> Semantic.Expr + -> Ty + -> BinaryArithmeticOp + -> Semantic.Expr + -> Ty + -> HoleIdentifier + -> Ty + -> ElabM (Maybe ([UnificationProblem], [ElabProblem])) +solveNoncanonicalBinaryArithmeticOpElabProblem gam loc lhs Duration BinaryArithmeticOp.Add rhs Timestamp hole typ = do + pure $ Just ([UnificationProblem loc typ Timestamp], [BinaryArithmeticOp $ + BinaryArithmeticOpElabProblem gam loc rhs Timestamp BinaryArithmeticOp.Add lhs Duration hole Timestamp]) +solveNoncanonicalBinaryArithmeticOpElabProblem gam loc lhs Timestamp BinaryArithmeticOp.Add rhs rhsTy hole typ = do + pure $ Just ([UnificationProblem loc rhsTy Duration, UnificationProblem loc typ Timestamp], + [BinaryArithmeticOp $ + BinaryArithmeticOpElabProblem gam loc lhs Timestamp BinaryArithmeticOp.Add rhs Duration hole Timestamp]) +solveNoncanonicalBinaryArithmeticOpElabProblem gam loc lhs lhsTy BinaryArithmeticOp.Add rhs Timestamp hole typ = do + pure $ Just ([UnificationProblem loc lhsTy Duration, UnificationProblem loc typ Timestamp], + [BinaryArithmeticOp $ + BinaryArithmeticOpElabProblem gam loc lhs Duration BinaryArithmeticOp.Add rhs Timestamp hole Timestamp]) +solveNoncanonicalBinaryArithmeticOpElabProblem gam loc lhs Timestamp BinaryArithmeticOp.Sub rhs rhsTy hole typ = do + pure $ Just ([UnificationProblem loc rhsTy Duration, UnificationProblem loc typ Timestamp], + [BinaryArithmeticOp $ + BinaryArithmeticOpElabProblem gam loc lhs Timestamp BinaryArithmeticOp.Sub rhs Duration hole Timestamp]) +solveNoncanonicalBinaryArithmeticOpElabProblem gam loc lhs Scalar op rhs (InstantVector Scalar) hole typ = do + pure (Just ([UnificationProblem loc typ (InstantVector Scalar)], [BinaryArithmeticOp $ + BinaryArithmeticOpElabProblem gam loc rhs (InstantVector Scalar) op lhs Scalar hole (InstantVector Scalar)])) +solveNoncanonicalBinaryArithmeticOpElabProblem gam loc lhs lhsTy op rhs _ hole Scalar = do + pure $ Just ([UnificationProblem loc lhsTy Scalar, UnificationProblem loc lhsTy Scalar], + [BinaryArithmeticOp $ BinaryArithmeticOpElabProblem gam loc lhs Scalar op rhs Scalar hole Scalar]) +solveNoncanonicalBinaryArithmeticOpElabProblem gam loc lhs Scalar op rhs Scalar hole holeTy = do + pure $ Just ([UnificationProblem loc holeTy Scalar], + [BinaryArithmeticOp $ BinaryArithmeticOpElabProblem gam loc lhs Scalar op rhs Scalar hole Scalar]) +solveNoncanonicalBinaryArithmeticOpElabProblem gam loc lhs lhsTy op rhs rhsTy hole holeTy + | lhsTy == InstantVector Scalar || rhsTy == InstantVector Scalar = + pure $ Just + ( + [UnificationProblem loc holeTy (InstantVector Scalar)], + [BinaryArithmeticOp $ + BinaryArithmeticOpElabProblem + gam + loc + lhs + lhsTy + op + rhs + rhsTy + hole + (InstantVector Scalar) + ] + ) +solveNoncanonicalBinaryArithmeticOpElabProblem _ _ _ _ _ _ _ _ _ = pure Nothing + +-- | Σ Γ ⊦ (a : A) `op` (b : B) ~> ?x : C +-- Assumes that all given `Ty` are normal w.r.t. hole substitution. +-- TODO: Check completeness +solveBinaryArithmeticOpElabProblem :: + Context + -> Loc + -> Semantic.Expr + -> Ty + -> BinaryArithmeticOp + -> Semantic.Expr + -> Ty + -> HoleIdentifier + -> Ty + -> ElabM (Maybe ([UnificationProblem], [ElabProblem])) +solveBinaryArithmeticOpElabProblem gam loc lhs lhsTy op rhs rhsTy hole holeTy = + solveCanonicalBinaryArithmeticOpElabProblem gam loc lhs lhsTy op rhs rhsTy hole holeTy >>= \case + Nothing -> solveNoncanonicalBinaryArithmeticOpElabProblem gam loc lhs lhsTy op rhs rhsTy hole holeTy + Just ok -> pure (Just ok) + +-- | Σ Γ ⊦ s ~> ?x : A +-- Assumes that the given `Ty` is normal w.r.t. hole substitution. +solveGeneralElabProblem :: Context -> Surface.Expr -> HoleIdentifier -> Ty -> ElabM ([UnificationProblem], [ElabProblem]) +solveGeneralElabProblem gam (mbBinaryRelation -> Just (l, a, r, b)) x typ = do + expectedA <- freshTyHole + expectedB <- freshTyHole + ah <- freshExprHole (Hole expectedA) + bh <- freshExprHole (Hole expectedB) + let e1 = General $ GeneralElabProblem gam a ah (Hole expectedA) + let e2 = General $ GeneralElabProblem gam b bh (Hole expectedB) + let e3 = BinaryRelation $ + BinaryRelationElabProblem + gam + l + (Semantic.Hole ah) + (Hole expectedA) + r + (Semantic.Hole bh) + (Hole expectedB) + x + typ + pure ([], [e1, e2, e3]) +solveGeneralElabProblem _ (Surface.Metrics l) x typ = do + let u = UnificationProblem l typ Types.Text + modify (updateDefs $ instantiateExpr x Semantic.Metrics) + pure ([u], []) +solveGeneralElabProblem _ (Surface.Number l f) x typ = do + let u = UnificationProblem l typ Scalar + modify (updateDefs $ instantiateExpr x (Semantic.Number f)) + pure ([u], []) +solveGeneralElabProblem _ (Surface.Truth l) x typ = do + let u = UnificationProblem l typ Bool + modify (updateDefs $ instantiateExpr x Semantic.True) + pure ([u], []) +solveGeneralElabProblem _ (Surface.Falsity l) x typ = do + let u = UnificationProblem l typ Bool + modify (updateDefs $ instantiateExpr x Semantic.False) + pure ([u], []) +solveGeneralElabProblem _ (Surface.Epoch l) x typ = do + let u = UnificationProblem l typ Timestamp + modify (updateDefs $ instantiateExpr x Semantic.Epoch) + pure ([u], []) +solveGeneralElabProblem _ (Surface.Now l) x typ = do + let u = UnificationProblem l typ Timestamp + modify (updateDefs $ instantiateExpr x Semantic.Now) + pure ([u], []) +solveGeneralElabProblem _ (Surface.Milliseconds l n) x typ = do + let u = UnificationProblem l typ Duration + modify $ updateDefs $ + instantiateExpr x $ Semantic.Milliseconds n + pure ([u], []) +solveGeneralElabProblem _ (Surface.Seconds l n) x typ = do + let u = UnificationProblem l typ Duration + modify $ updateDefs $ + instantiateExpr x $ Semantic.Seconds n + pure ([u], []) +solveGeneralElabProblem _ (Surface.Minutes l n) x typ = do + let u = UnificationProblem l typ Duration + modify $ updateDefs $ + instantiateExpr x $ Semantic.Minutes n + pure ([u], []) +solveGeneralElabProblem _ (Surface.Hours l n) x typ = do + let u = UnificationProblem l typ Duration + modify $ updateDefs $ + instantiateExpr x $ Semantic.Hours n + pure ([u], []) +solveGeneralElabProblem gam (Surface.Or l a b) x typ = do + let u = UnificationProblem l typ Bool + ah <- freshExprHole Bool + bh <- freshExprHole Bool + let e1 = General $ GeneralElabProblem gam a ah Bool + let e2 = General $ GeneralElabProblem gam b bh Bool + modify $ updateDefs $ + instantiateExpr x $ Semantic.Or (Semantic.Hole ah) (Semantic.Hole bh) + pure ([u], [e1, e2]) +solveGeneralElabProblem gam (Surface.And l a b) x typ = do + let u = UnificationProblem l typ Bool + ah <- freshExprHole Bool + bh <- freshExprHole Bool + let e1 = General $ GeneralElabProblem gam a ah Bool + let e2 = General $ GeneralElabProblem gam b bh Bool + modify $ updateDefs $ + instantiateExpr x $ Semantic.And (Semantic.Hole ah) (Semantic.Hole bh) + pure ([u], [e1, e2]) +solveGeneralElabProblem gam (Surface.Not l a) x typ = do + let u = UnificationProblem l typ Bool + x' <- freshExprHole Bool + let e1 = General $ GeneralElabProblem gam a x' Bool + modify $ updateDefs $ + instantiateExpr x $ Semantic.Not (Semantic.Hole x') + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.Abs l a) x typ = do + let u = UnificationProblem l typ Scalar + x' <- freshExprHole Scalar + let e1 = General $ GeneralElabProblem gam a x' Scalar + modify $ updateDefs $ + instantiateExpr x $ Semantic.Abs (Semantic.Hole x') + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.Round l a) x typ = do + let u = UnificationProblem l typ Scalar + x' <- freshExprHole Scalar + let e1 = General $ GeneralElabProblem gam a x' Scalar + modify $ updateDefs $ + instantiateExpr x $ Semantic.RoundScalar (Semantic.Hole x') + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.Increase l a) x typ = do + let u = UnificationProblem l typ (InstantVector Scalar) + x' <- freshExprHole (RangeVector Scalar) + let e1 = General $ GeneralElabProblem gam a x' (RangeVector Scalar) + modify $ updateDefs $ + instantiateExpr x $ Semantic.Increase (Semantic.Hole x') + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.Rate l a) x typ = do + let u = UnificationProblem l typ (InstantVector Scalar) + x' <- freshExprHole (RangeVector Scalar) + let e1 = General $ GeneralElabProblem gam a x' (RangeVector Scalar) + modify $ updateDefs $ + instantiateExpr x $ Semantic.Rate (Semantic.Hole x') + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.Max l a) x typ = do + let u = UnificationProblem l typ Scalar + x' <- freshExprHole (InstantVector Scalar) + let e1 = General $ GeneralElabProblem gam a x' (InstantVector Scalar) + modify $ updateDefs $ + instantiateExpr x $ Semantic.Max (Semantic.Hole x') + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.Min l v) x typ = do + let u = UnificationProblem l typ Scalar + vh <- freshExprHole (InstantVector Scalar) + let e1 = General $ GeneralElabProblem gam v vh (InstantVector Scalar) + modify $ updateDefs $ + instantiateExpr x $ Semantic.Min (Semantic.Hole vh) + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.Avg l v) x typ = do + let u = UnificationProblem l typ Scalar + vh <- freshExprHole (InstantVector Scalar) + let e1 = General $ GeneralElabProblem gam v vh (InstantVector Scalar) + modify $ updateDefs $ + instantiateExpr x $ Semantic.Avg (Semantic.Hole vh) + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.AvgOverTime l r) x typ = do + let u = UnificationProblem l typ (InstantVector Scalar) + rh <- freshExprHole (RangeVector Scalar) + let e1 = General $ GeneralElabProblem gam r rh (RangeVector Scalar) + modify $ updateDefs $ + instantiateExpr x $ Semantic.AvgOverTime (Semantic.Hole rh) + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.SumOverTime l r) x typ = do + let u = UnificationProblem l typ (InstantVector Scalar) + rh <- freshExprHole (RangeVector Scalar) + let e1 = General $ GeneralElabProblem gam r rh (RangeVector Scalar) + modify $ updateDefs $ + instantiateExpr x $ Semantic.AvgOverTime (Semantic.Hole rh) + pure ([u], [e1]) +solveGeneralElabProblem gam (Surface.QuantileOverTime l k r) x typ = do + let u = UnificationProblem l typ (InstantVector Scalar) + rh <- freshExprHole (RangeVector Scalar) + let e1 = General $ GeneralElabProblem gam r rh (RangeVector Scalar) + kh <- freshExprHole Scalar + let e2 = General $ GeneralElabProblem gam k kh Scalar + modify $ updateDefs $ + instantiateExpr x $ Semantic.QuantileOverTime (Semantic.Hole kh) (Semantic.Hole rh) + pure ([u], [e1, e2]) +solveGeneralElabProblem gam (Surface.QuantileBy loc ls k v) x typ = do + let u = UnificationProblem loc typ (InstantVector Scalar) + vh <- freshExprHole (InstantVector Scalar) + let e1 = General $ GeneralElabProblem gam v vh (InstantVector Scalar) + kh <- freshExprHole Scalar + let e2 = General $ GeneralElabProblem gam k kh Scalar + modify $ updateDefs $ + instantiateExpr x $ Semantic.QuantileBy + ls (Semantic.Hole kh) (Semantic.Hole vh) + pure ([u], [e1, e2]) +solveGeneralElabProblem gam (Surface.Range l expr t0 t1 Nothing) x typ = do + tyh <- freshTyHole + let u = UnificationProblem l typ (RangeVector (Hole tyh)) + exprh <- freshExprHole (Fun Timestamp (InstantVector (Hole tyh))) + t0h <- freshExprHole Timestamp + t1h <- freshExprHole Timestamp + let e1 = General $ GeneralElabProblem gam expr exprh (Fun Timestamp (InstantVector (Hole tyh))) + let e2 = General $ GeneralElabProblem gam t0 t0h Timestamp + let e3 = General $ GeneralElabProblem gam t1 t1h Timestamp + modify $ updateDefs $ + instantiateExpr x $ + Semantic.Range + (Semantic.Hole exprh) + (Semantic.Hole t0h) + (Semantic.Hole t1h) + Nothing + pure ([u], [e1, e2, e3]) +solveGeneralElabProblem gam (Surface.Range l expr t0 t1 (Just step)) x typ = do + tyh <- freshTyHole + let u = UnificationProblem l typ (RangeVector (Hole tyh)) + exprh <- freshExprHole (Fun Timestamp (InstantVector (Hole tyh))) + t0h <- freshExprHole Timestamp + t1h <- freshExprHole Timestamp + steph <- freshExprHole Duration + let e1 = General $ GeneralElabProblem gam expr exprh (Fun Timestamp (InstantVector (Hole tyh))) + let e2 = General $ GeneralElabProblem gam t0 t0h Timestamp + let e3 = General $ GeneralElabProblem gam t1 t1h Timestamp + let e4 = General $ GeneralElabProblem gam step steph Duration + modify $ updateDefs $ + instantiateExpr x $ + Semantic.Range + (Semantic.Hole exprh) + (Semantic.Hole t0h) + (Semantic.Hole t1h) + (Just (Semantic.Hole steph)) + pure ([u], [e1, e2, e3, e4]) +solveGeneralElabProblem gam (Surface.Fst l t) x typ = do + tyah <- freshTyHole + tybh <- freshTyHole + let u = UnificationProblem l typ (Hole tyah) + th <- freshExprHole (Ty.Pair (Hole tyah) (Hole tybh)) + let e = General $ GeneralElabProblem gam t th (Ty.Pair (Hole tyah) (Hole tybh)) + modify $ updateDefs $ + instantiateExpr x $ Semantic.Fst (Semantic.Hole th) + pure ([u], [e]) +solveGeneralElabProblem gam (Surface.Snd l t) x typ = do + tyah <- freshTyHole + tybh <- freshTyHole + let u = UnificationProblem l typ (Hole tybh) + th <- freshExprHole (Ty.Pair (Hole tyah) (Hole tybh)) + let e = General $ GeneralElabProblem gam t th (Ty.Pair (Hole tyah) (Hole tybh)) + modify $ updateDefs $ + instantiateExpr x $ Semantic.Snd (Semantic.Hole th) + pure ([u], [e]) +solveGeneralElabProblem gam (Surface.MkPair l a b) x typ = do + tyah <- freshTyHole + tybh <- freshTyHole + let u = UnificationProblem l typ (Ty.Pair (Hole tyah) (Hole tybh)) + ah <- freshExprHole (Hole tyah) + bh <- freshExprHole (Hole tybh) + let e1 = General $ GeneralElabProblem gam a ah (Hole tyah) + let e2 = General $ GeneralElabProblem gam b bh (Hole tybh) + modify $ updateDefs $ + instantiateExpr x $ + Semantic.MkPair + (Semantic.Hole ah) + (Semantic.Hole bh) + pure ([u], [e1, e2]) +solveGeneralElabProblem gam (Surface.Lambda l v scope) x typ = do + tyah <- freshTyHole + tybh <- freshTyHole + checkFresh gam v + let u = UnificationProblem l typ (Fun (Hole tyah) (Hole tybh)) + scopeh <- freshExprHole (Hole tybh) + let e = General $ GeneralElabProblem (gam |> LambdaBinding v (Hole tyah)) scope scopeh (Hole tybh) + modify $ updateDefs $ + instantiateExpr x $ + Semantic.Lambda + v + (Semantic.Hole scopeh) + pure ([u], [e]) +solveGeneralElabProblem gam (Surface.Let l v rhs scope) x typ = do + tyah <- freshTyHole + tybh <- freshTyHole + checkFresh gam v + let u = UnificationProblem l typ (Hole tybh) + rhsh <- freshExprHole (Hole tyah) + scopeh <- freshExprHole (Hole tybh) + let e1 = General $ GeneralElabProblem gam rhs rhsh (Hole tyah) + let e2 = General $ GeneralElabProblem (gam |> LetBinding v (Semantic.Hole rhsh) (Hole tyah)) scope scopeh (Hole tybh) + modify $ updateDefs $ + instantiateExpr x $ + Semantic.Let + v + (Semantic.Hole rhsh) + (Semantic.Hole scopeh) + pure ([u], [e1, e2]) +solveGeneralElabProblem gam (mbBinaryArithmeticOp -> Just (loc, left, op, right)) x typ = do + tyah <- freshTyHole + tybh <- freshTyHole + lefth <- freshExprHole typ + righth <- freshExprHole typ + let e1 = General $ GeneralElabProblem gam left lefth (Hole tyah) + let e2 = General $ GeneralElabProblem gam right righth (Hole tybh) + let e3 = BinaryArithmeticOp $ + BinaryArithmeticOpElabProblem gam loc (Semantic.Hole lefth) (Hole tyah) op (Semantic.Hole righth) (Hole tybh) x typ + pure ([], [e1, e2, e3]) +solveGeneralElabProblem gam (Surface.Variable l v) x typ | Just b <- find (\b -> Types.identifier b == v) gam = do + modify $ updateDefs $ instantiateExpr x $ Semantic.Variable v + pure ([UnificationProblem l typ (Types.ty b)], []) +-- Assumes that all variables into the store (= metrics) have type (Timestamp -> Scalar) +solveGeneralElabProblem _ (Surface.Variable l v) x typ = do + modify $ updateDefs $ instantiateExpr x $ Semantic.Variable v + pure ([UnificationProblem l typ (Fun Timestamp (InstantVector Scalar))], []) +solveGeneralElabProblem gam (Surface.Filter l f v) h hty = do + argTy <- freshTyHole + fh <- freshExprHole (Fun (Hole argTy) Bool) + vh <- freshExprHole (InstantVector (Hole argTy)) + modify $ updateDefs $ instantiateExpr h $ + Semantic.Filter (Semantic.Hole fh) (Semantic.Hole vh) + pure ([UnificationProblem l hty (InstantVector (Hole argTy))], + [General $ GeneralElabProblem gam f fh (Fun (Hole argTy) Bool), + General $ GeneralElabProblem gam v vh (InstantVector (Hole argTy)) + ] + ) +solveGeneralElabProblem gam (Surface.FilterByLabel loc ls v) h hty = do + argTy <- freshTyHole + vh <- freshExprHole (InstantVector (Hole argTy)) + modify $ updateDefs $ instantiateExpr h $ + Semantic.FilterByLabel ls (Semantic.Hole vh) + pure ([UnificationProblem loc hty (InstantVector (Hole argTy))], + [General $ GeneralElabProblem gam v vh (InstantVector (Hole argTy))] + ) +solveGeneralElabProblem gam (Surface.Map l f v) h hty = do + aTy <- freshTyHole + bTy <- freshTyHole + fh <- freshExprHole (Fun (Hole aTy) (Hole bTy)) + vh <- freshExprHole (InstantVector (Hole aTy)) + modify $ updateDefs $ instantiateExpr h $ + Semantic.Map (Semantic.Hole fh) (Semantic.Hole vh) + pure ([UnificationProblem l hty (InstantVector (Hole bTy))], + [General $ GeneralElabProblem gam f fh (Fun (Hole aTy) (Hole bTy)), + General $ GeneralElabProblem gam v vh (InstantVector (Hole aTy)) + ] + ) +solveGeneralElabProblem gam (Surface.Join l v u) h hty = do + aTy <- freshTyHole + bTy <- freshTyHole + vh <- freshExprHole (InstantVector (Hole aTy)) + uh <- freshExprHole (InstantVector (Hole bTy)) + modify $ updateDefs $ instantiateExpr h $ + Semantic.Join (Semantic.Hole vh) (Semantic.Hole uh) + pure ([UnificationProblem l hty (InstantVector (Ty.Pair (Hole aTy) (Hole bTy)))], + [General $ GeneralElabProblem gam v vh (InstantVector (Hole aTy)), + General $ GeneralElabProblem gam u uh (InstantVector (Hole bTy)) + ] + ) +solveGeneralElabProblem gam (Surface.Unless l v u) h hty = do + aTy <- freshTyHole + bTy <- freshTyHole + vh <- freshExprHole (InstantVector (Hole aTy)) + uh <- freshExprHole (InstantVector (Hole bTy)) + modify $ updateDefs $ instantiateExpr h $ + Semantic.Unless (Semantic.Hole vh) (Semantic.Hole uh) + pure ([UnificationProblem l hty (InstantVector (Hole aTy))], + [General $ GeneralElabProblem gam v vh (InstantVector (Hole aTy)), + General $ GeneralElabProblem gam u uh (InstantVector (Hole bTy)) + ] + ) +solveGeneralElabProblem gam (Surface.App l f e) h hty = do + aTy <- freshTyHole + bTy <- freshTyHole + fh <- freshExprHole (Fun (Hole aTy) (Hole bTy)) + eh <- freshExprHole (Hole aTy) + modify $ updateDefs $ instantiateExpr h $ + Semantic.Application (Semantic.Hole fh) (Semantic.Hole eh) + pure ([UnificationProblem l hty (Hole bTy)], + [General $ GeneralElabProblem gam f fh (Fun (Hole aTy) (Hole bTy)), + General $ GeneralElabProblem gam e eh (Hole aTy) + ] + ) +solveGeneralElabProblem gam (Surface.ToScalar l t) h hty = do + tTy <- freshTyHole + th <- freshExprHole (Hole tTy) + pure ([UnificationProblem l hty Scalar], + [ + General $ GeneralElabProblem gam t th (Hole tTy) + , + ToScalar $ ToScalarElabProblem gam l (Semantic.Hole th) (Hole tTy) h + ]) +solveGeneralElabProblem _ s _ _ = throwError $ + "Do not know how to elaborate: " <> showT s + +solveElabProblem :: ElabProblem -> ElabM (Maybe ([UnificationProblem], [ElabProblem])) +solveElabProblem (General (GeneralElabProblem gam s h typ)) = do + defs <- defs <$> get + let typ' = resolveTy defs typ + let gam' = resolveContext defs gam + Just <$> solveGeneralElabProblem gam' s h typ' +solveElabProblem (BinaryArithmeticOp (BinaryArithmeticOpElabProblem gam loc lhs lhsTy op rhs rhsTy hole holeTy)) = do + defs <- defs <$> get + let gam' = resolveContext defs gam + let lhsTy' = resolveTy defs lhsTy + let rhsTy' = resolveTy defs rhsTy + let holeTy' = resolveTy defs holeTy + solveBinaryArithmeticOpElabProblem gam' loc lhs lhsTy' op rhs rhsTy' hole holeTy' +solveElabProblem (BinaryRelation (BinaryRelationElabProblem gam loc lhs lhsTy rel rhs rhsTy hole holeTy)) = do + defs <- defs <$> get + let gam' = resolveContext defs gam + let lhsTy' = resolveTy defs lhsTy + let rhsTy' = resolveTy defs rhsTy + let holeTy' = resolveTy defs holeTy + solveBinaryRelationElabProblem gam' loc lhs lhsTy' rel rhs rhsTy' hole holeTy' +solveElabProblem (ToScalar (ToScalarElabProblem gam loc t tTy hole)) = do + defs <- defs <$> get + let gam' = resolveContext defs gam + let tTy' = resolveTy defs tTy + solveToScalarElabProblem gam' loc t tTy' hole + +solveH :: Bool -> Seq ElabProblem -> Seq ElabProblem -> ElabM (Bool, Seq ElabProblem) +solveH progress stuck Empty = pure (progress, stuck) +solveH progress stuck (p :<| ps) = do + solveElabProblem p >>= \case + Nothing -> solveH progress (stuck |> p) ps + Just (us, es) -> runUnifyM (Unify.solve us) >> solveH True stuck (fromList es >< ps) + +solve :: Seq ElabProblem -> ElabM () +solve Empty = pure () +solve problems = + solveH False Empty problems >>= \case + (True, stuck) -> solve stuck + (False, stuck) -> do + defs <- defs <$> get + let toShow = fmap (asText . evalElabProblem defs) stuck + throwError $ "Can't solve elaboration problems:\n" <> + Text.unlines (Foldable.toList toShow) + +-- | Given a surface query `Surface.Expr` elaborate it into a regular "semantic" query `Semantic.Expr`. +elab :: Surface.Expr -> ElabM Semantic.Expr +elab expr = do + typ <- freshTyHole + t <- freshExprHole (Hole typ) + solve $ Seq.singleton (General $ GeneralElabProblem Seq.Empty expr t (Hole typ)) + ds <- getDefs <$> get + pure $ resolveExpr' ds (Semantic.Hole t) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr.hs new file mode 100644 index 00000000000..2d2258314a1 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr.hs @@ -0,0 +1,233 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# OPTIONS_GHC -Wno-orphans #-} +module Cardano.Timeseries.Elab.Expr(Expr(..), mkRange, mkApp, Loc, getLoc) where + +import Cardano.Timeseries.AsText +import Cardano.Timeseries.Domain.Identifier (Identifier) +import Cardano.Timeseries.Domain.Types (Label) +import Cardano.Timeseries.Interp.Expr (LabelConstraint) + +import Prelude hiding (Foldable (..)) + +import Data.Foldable (Foldable (..)) +import Data.Set (Set) +import Data.Text (Text, pack) +import Data.Word (Word64) +import Text.Megaparsec (SourcePos, sourcePosPretty) + +-- ---- not ---- +-- not < atom +-- ---- range ---- +-- range < atom +-- ---- app ---- +-- app < atom +-- app < not +-- app < range +-- ---- add ---- +-- add < atom +-- add < not +-- add < range +-- add < app +-- ---- mul ---- +-- mul < atom +-- mul < not +-- mul < range +-- mul < app +-- mul < add +-- ---- comp ---- +-- comp < atom +-- comp < not +-- comp < range +-- comp < app +-- comp < add +-- comp < mul +-- ---- and ---- +-- and < atom +-- and < not +-- and < range +-- and < app +-- and < add +-- and < mul +-- and < comp +-- ---- or ---- +-- or < atom +-- or < not +-- or < range +-- or < app +-- or < add +-- or < mul +-- or < comp +-- or < and +-- ---- universe ---- +-- universe < atom +-- universe < not +-- universe < range +-- universe < app +-- universe < add +-- universe < mul +-- universe < comp +-- universe < and +-- universe < or + +-- s ::= +-- lc ::= s = s | s != s // label constraint +-- l̅c̅ ::= {lc, ..., .lc} +-- t{atom} ::= (t{≥ universe}, t{≥ universe}) +-- | x +-- | epoch +-- | now +-- | true +-- | false +-- | ms +-- | s +-- | m +-- | h +-- | (t{≥ universe}) +-- | +-- | "" +-- t{not} ::= !t{> not} +-- t{range} ::= t{> range} l̅c̅ +-- | t{> range} [̅t̅{̅≥̅ ̅u̅n̅i̅v̅e̅r̅s̅e̅}̅;̅ ̅t̅{̅≥̅ ̅u̅n̅i̅v̅e̅r̅s̅e̅}̅]̅ ̅|̅ ̅t̅[̅t̅{̅≥̅ ̅u̅n̅i̅v̅e̅r̅s̅e̅}̅;̅ ̅t̅{̅≥̅ ̅u̅n̅i̅v̅e̅r̅s̅e̅}̅ ̅:̅ ̅t̅{̅≥̅ ̅u̅n̅i̅v̅e̅r̅s̅e̅}̅]̅ +-- t{app} ::= fst t{> app} | snd t{> app} +-- | min t{> app} | max t{> app} | avg t{> app} | filter t{> app} t{> app} +-- | join t{> app} t{> app} +-- | map t{> app} t{> app} +-- | round t{> app} +-- | abs t{> app} +-- | increase t{> app} +-- | rate t{> app} +-- | avg_over_time t{> app} +-- | sum_over_time t{> app} +-- | quantile_over_time t{> app} t{> app} +-- | unless t{> app} t{> app} +-- | quantile_by (s, ..., s) t{> app} t{> app} +-- | earliest x +-- | latest x +-- | to_scalar t{> app} +-- | t{> app} t̅{̅>̅ ̅a̅p̅p̅}̅ +-- t{mul} ::= t{> mul} *̅|̅/̅ ̅t̅{̅>̅ ̅m̅u̅l̅}̅ +-- t{add} ::= t{> add} +̅|̅-̅ ̅t̅{̅>̅ ̅a̅d̅d̅}̅ +-- t{comp} ::= t{> comp} == t{> comp} | t{> comp} != t{> comp} | t{> comp} < t{> comp} | t{> comp} <= t{> comp} +-- | t{> comp} > t{> comp} | t{> comp} >= t{> comp} +-- t{and} ::= t{> and} &̅&̅ ̅t̅{̅>̅ ̅a̅n̅d̅}̅ +-- t{or} ::= t{> or} |̅|̅ ̅t̅{̅>̅ ̅o̅r̅}̅ +-- t{universe} ::= let x = t{> universe} in t{≥ universe} | \x -> t{≥ universe} + +-- | Source location. +type Loc = SourcePos + +instance AsText Loc where + asText = pack . sourcePosPretty + +data Expr = + Let Loc Identifier Expr Expr + | Lambda Loc Identifier Expr + | Fst Loc Expr + | Snd Loc Expr + | MkPair Loc Expr Expr + | Eq Loc Expr Expr + | NotEq Loc Expr Expr + | Lt Loc Expr Expr + | Lte Loc Expr Expr + | Gt Loc Expr Expr + | Gte Loc Expr Expr + | Add Loc Expr Expr + | Sub Loc Expr Expr + | Mul Loc Expr Expr + | Div Loc Expr Expr + | Not Loc Expr + | Or Loc Expr Expr + | And Loc Expr Expr + | Milliseconds Loc Word64 + | Seconds Loc Word64 + | Minutes Loc Word64 + | Hours Loc Word64 + | Epoch Loc + | Now Loc + | Range Loc Expr Expr Expr (Maybe Expr) + | FilterByLabel Loc (Set LabelConstraint) Expr + | Max Loc Expr + | Min Loc Expr + | Avg Loc Expr + | Filter Loc Expr Expr + | Join Loc Expr Expr + | Map Loc Expr Expr + | Round Loc Expr + | Abs Loc Expr + | Increase Loc Expr + | Rate Loc Expr + | AvgOverTime Loc Expr + | SumOverTime Loc Expr + | QuantileOverTime Loc Expr Expr + | Unless Loc Expr Expr + | QuantileBy Loc (Set Label) Expr Expr + | Earliest Loc Identifier + | Latest Loc Identifier + | Metrics Loc + | ToScalar Loc Expr + | Variable Loc Identifier + | Str Loc Text + | Number Loc Double + | Truth Loc + | Falsity Loc + | App Loc Expr Expr deriving (Show) + +getLoc :: Expr -> Loc +getLoc (Let l _ _ _) = l +getLoc (Lambda l _ _) = l +getLoc (Fst l _) = l +getLoc (Snd l _) = l +getLoc (MkPair l _ _) = l +getLoc (Eq l _ _) = l +getLoc (NotEq l _ _) = l +getLoc (Lt l _ _) = l +getLoc (Lte l _ _) = l +getLoc (Gt l _ _) = l +getLoc (Gte l _ _) = l +getLoc (Add l _ _) = l +getLoc (Sub l _ _) = l +getLoc (Mul l _ _) = l +getLoc (Div l _ _) = l +getLoc (Not l _) = l +getLoc (Or l _ _) = l +getLoc (And l _ _) = l +getLoc (Milliseconds l _) = l +getLoc (Seconds l _) = l +getLoc (Minutes l _) = l +getLoc (Hours l _) = l +getLoc (Epoch l) = l +getLoc (Now l) = l +getLoc (Range l _ _ _ _) = l +getLoc (FilterByLabel l _ _) = l +getLoc (Max l _) = l +getLoc (Min l _) = l +getLoc (Avg l _) = l +getLoc (Filter l _ _) = l +getLoc (Join l _ _) = l +getLoc (Map l _ _) = l +getLoc (Abs l _) = l +getLoc (Round l _) = l +getLoc (Increase l _) = l +getLoc (Rate l _) = l +getLoc (AvgOverTime l _) = l +getLoc (SumOverTime l _) = l +getLoc (QuantileOverTime l _ _) = l +getLoc (Unless l _ _) = l +getLoc (QuantileBy l _ _ _) = l +getLoc (Earliest l _) = l +getLoc (Latest l _) = l +getLoc (Metrics l) = l +getLoc (ToScalar l _) = l +getLoc (Variable l _) = l +getLoc (Str l _) = l +getLoc (Number l _) = l +getLoc (Truth l) = l +getLoc (Falsity l) = l +getLoc (App l _ _) = l + +mkRange :: Loc -> Expr -> Either (Expr, Expr, Maybe Expr) (Set LabelConstraint) -> Expr +mkRange loc t (Left (a, b, c)) = Range loc t a b c +mkRange loc t (Right set) = FilterByLabel loc set t + +mkApp :: Loc -> Expr -> [Expr] -> Expr +mkApp l = foldl' (App l) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr/Head.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr/Head.hs new file mode 100644 index 00000000000..cf4e1c9518b --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr/Head.hs @@ -0,0 +1,27 @@ +module Cardano.Timeseries.Elab.Expr.Head(Head(..)) where +import Cardano.Timeseries.Domain.Identifier (Identifier) +import Cardano.Timeseries.Domain.Types (Label) + +import Data.Set (Set) + +data Head = Fst + | Snd + | Min + | Max + | Avg + | Filter + | Join + | Map + | Round + | Abs + | Increase + | Rate + | AvgOverTime + | SumOverTime + | QuantileOverTime + | Unless + | QuantileBy (Set Label) + | Earliest Identifier + | Latest Identifier + | ToScalar + | Metrics deriving (Show) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr/Parser.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr/Parser.hs new file mode 100644 index 00000000000..72362d095f8 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Expr/Parser.hs @@ -0,0 +1,376 @@ +{- HLINT ignore "Use <$>" -} +module Cardano.Timeseries.Elab.Expr.Parser(Parser, expr) where + +import Cardano.Timeseries.Domain.Identifier (Identifier (User)) +import Cardano.Timeseries.Domain.Types (Label) +import Cardano.Timeseries.Elab.Expr +import Cardano.Timeseries.Elab.Expr.Head (Head) +import qualified Cardano.Timeseries.Elab.Expr.Head as Head +import Cardano.Timeseries.Interp.Expr (LabelConstraint (..)) + +import Prelude hiding (Foldable (..), head) + +import Control.Applicative hiding (many, some) +import Control.Monad (guard) +import Data.Char (isAlpha, isAlphaNum) +import Data.Foldable (Foldable (..)) +import Data.Functor (void) +import Data.Scientific (toRealFloat) +import Data.Set (Set) +import qualified Data.Set as Set +import Data.Text (Text) +import qualified Data.Text as Text +import Data.Void (Void) +import GHC.Unicode (isControl) +import Text.Megaparsec +import Text.Megaparsec.Char (char, space, space1, string) +import Text.Megaparsec.Char.Lexer (decimal, scientific, signed) + +type Parser = Parsec Void Text + +keywords :: [Text] +keywords = ["let", "in", "true", "false", "epoch", "now", "fst", "snd", + "min", "max", "avg", "filter", "join", "map", "abs", "increase", + "rate", "avg_over_time", "sum_over_time", "quantile_over_time", "unless", + "quantile_by", "earliest", "latest", "to_scalar", "metrics"] + +unescapedVariableIdentifierNextChar :: Parser Char +unescapedVariableIdentifierNextChar = satisfy (\x -> isAlphaNum x || x == '_') + +unescapedVariableIdentifier :: Parser Text +unescapedVariableIdentifier = + Text.pack <$> ((:) <$> firstChar <*> many unescapedVariableIdentifierNextChar) "identifier" where + firstChar :: Parser Char + firstChar = satisfy (\x -> isAlpha x || x == '_') + +number :: Parser Expr +number = + Number <$> getSourcePos <*> (toRealFloat <$> signed (pure ()) scientific "number") + +escapedVariableIdentifier :: Parser Text +escapedVariableIdentifier = Text.pack <$> (char '`' *> manyTill one (char '`')) where + one :: Parser Char + one = satisfy (\x -> not (isControl x) && (x /= '`') && (x /= '\n') && (x /= '\r')) + +literalVariableIdentifier :: Parser Text +literalVariableIdentifier = do + x <- unescapedVariableIdentifier + guard (x `notElem` keywords) + pure x + +variableIdentifier :: Parser Identifier +variableIdentifier = User <$> (literalVariableIdentifier <|> escapedVariableIdentifier) + +variable :: Parser Expr +variable = Variable <$> getSourcePos <*> variableIdentifier + +text :: Parser Text +text = Text.pack <$> (char '\"' *> many one) <* char '\"' where + one :: Parser Char + one = satisfy (\x -> not (isControl x) && (x /= '"') && (x /= '\n') && (x /= '\r')) + +str :: Parser Expr +str = Str <$> getSourcePos <*> text + +milliseconds :: Parser Expr +milliseconds = Milliseconds <$> getSourcePos <*> decimal <* string "ms" <* notFollowedBy (satisfy isAlpha) + +seconds :: Parser Expr +seconds = Seconds <$> getSourcePos <*> decimal <* string "s" <* notFollowedBy (satisfy isAlpha) + +minutes :: Parser Expr +minutes = Minutes <$> getSourcePos <*> decimal <* string "m" <* notFollowedBy (satisfy isAlpha) + +hours :: Parser Expr +hours = Hours <$> getSourcePos <*> decimal <* string "h" <* notFollowedBy (satisfy isAlpha) + +now :: Parser Expr +now = Now <$> getSourcePos <* string "now" + +epoch :: Parser Expr +epoch = Now <$> getSourcePos <* string "epoch" + +true :: Parser Expr +true = Truth <$> getSourcePos <* string "true" + +false :: Parser Expr +false = Falsity <$> getSourcePos <* string "false" + +continueTight :: Expr -> Parser Expr +continueTight a = a <$ string ")" + +continuePair :: Loc -> Expr -> Parser Expr +continuePair l a = do + void $ string "," + space + b <- exprUniverse + space + void $ string ")" + pure (MkPair l a b) + +tightOrPair :: Parser Expr +tightOrPair = do + l <- getSourcePos + void $ string "(" + space + a <- exprUniverse + space + try (continuePair l a) <|> continueTight a + +exprAtom :: Parser Expr +exprAtom = tightOrPair + <|> epoch + <|> true + <|> false + <|> now + <|> variable + <|> try milliseconds + <|> try seconds + <|> try minutes + <|> try hours + <|> number + <|> str + +exprNot :: Parser Expr +exprNot = Not <$> getSourcePos <*> (string "!" *> space *> exprAtom) + +range :: Parser (Expr, Expr, Maybe Expr) +range = do + void $ string "[" + space + a <- exprUniverse + space + void $ string ";" + space + b <- exprUniverse + c <- optional $ do + space + void $ string ":" + space + c <- exprUniverse + space + pure c + void $ string "]" + pure (a, b, c) + +exprRange :: Parser Expr +exprRange = do + l <- getSourcePos + head <- exprAtom + ext <- many (try $ space *> (try (Left <$> range) <|> Right <$> labelConstraints)) + pure $ foldl' (mkRange l) head ext + +labelConstraint :: Parser LabelConstraint +labelConstraint = do + x <- text + space + c <- Left () <$ string "=" <|> Right () <$ string "!=" + space + v <- text + pure (mk x c v) where + mk x (Left _) v = LabelConstraintEq (x, v) + mk x (Right _) v = LabelConstraintNotEq (x, v) + +labelConstraints :: Parser (Set LabelConstraint) +labelConstraints = do + void $ string "{" + space + list <- sepBy labelConstraint (space *> string "," <* space) + space + void $ string "}" + pure $ Set.fromList list + +setLabel :: Parser (Set Label) +setLabel = do + void $ string "(" + space + list <- sepBy text (space *> string "," <* space) + space + void $ string ")" + pure $ Set.fromList list + +headParse :: Parser Head +headParse = ( + Head.Fst <$ string "fst" + <|> Head.Snd <$ string "snd" + <|> Head.Min <$ string "min" + <|> Head.Max <$ string "max" + <|> Head.Filter <$ string "filter" + <|> Head.Join <$ string "join" + <|> Head.Map <$ string "map" + <|> Head.Abs <$ string "abs" + <|> Head.Round <$ string "round" + <|> Head.Increase <$ string "increase" + <|> Head.Rate <$ string "rate" + <|> Head.AvgOverTime <$ string "avg_over_time" + <|> Head.Avg <$ string "avg" + <|> Head.SumOverTime <$ string "sum_over_time" + <|> Head.QuantileOverTime <$ string "quantile_over_time" + <|> Head.Unless <$ string "unless" + <|> Head.QuantileBy <$> (string "quantile_by" *> space1 *> setLabel) + <|> Head.Earliest <$> (string "earliest" *> space1 *> variableIdentifier) + <|> Head.Latest <$> (string "latest" *> space1 *> variableIdentifier) + <|> Head.ToScalar <$ string "to_scalar" + <|> Head.Metrics <$ string "metrics" + ) <* notFollowedBy unescapedVariableIdentifierNextChar + +wrongNumberOfArguments :: Int -> String -> Parser a +wrongNumberOfArguments n head = fail $ "Wrong number of arguments (" <> show n <> ") for `" <> head <> "`" + +applyBuiltin :: Loc -> Head -> [Expr] -> Parser Expr +applyBuiltin l Head.Fst [t] = pure $ Fst l t +applyBuiltin l Head.Snd [t] = pure $ Snd l t +applyBuiltin l Head.Min [t] = pure $ Min l t +applyBuiltin l Head.Max [t] = pure $ Max l t +applyBuiltin l Head.Avg [t] = pure $ Avg l t +applyBuiltin l Head.Filter [f, xs] = pure $ Filter l f xs +applyBuiltin l Head.Join [xs, ys] = pure $ Join l xs ys +applyBuiltin l Head.Map [f, xs] = pure $ Map l f xs +applyBuiltin l Head.Abs [t] = pure $ Abs l t +applyBuiltin l Head.Round [t] = pure $ Round l t +applyBuiltin l Head.Increase [xs] = pure $ Increase l xs +applyBuiltin l Head.Rate [xs] = pure $ Rate l xs +applyBuiltin l Head.AvgOverTime [xs] = pure $ AvgOverTime l xs +applyBuiltin l Head.SumOverTime [xs] = pure $ SumOverTime l xs +applyBuiltin l Head.QuantileOverTime [k, xs] = pure $ QuantileOverTime l k xs +applyBuiltin l Head.Unless [xs, ys] = pure $ Unless l xs ys +applyBuiltin l (Head.QuantileBy ls) [k, xs] = pure $ QuantileBy l ls k xs +applyBuiltin l (Head.Earliest x) [] = pure $ Earliest l x +applyBuiltin l (Head.Latest x) [] = pure $ Latest l x +applyBuiltin l Head.ToScalar [t] = pure $ ToScalar l t +applyBuiltin l Head.Metrics [] = pure $ Metrics l +applyBuiltin _ h args = wrongNumberOfArguments (length args) (show h) + +apply :: Loc -> Either Head Expr -> [Expr] -> Parser Expr +apply l (Left t) = applyBuiltin l t +apply l (Right t) = pure . mkApp l t + +exprAppArg :: Parser Expr +exprAppArg = try exprNot <|> exprRange + +exprApp :: Parser Expr +exprApp = do + l <- getSourcePos + h <- try (Left <$> headParse) <|> Right <$> exprAppArg + args <- many (try (space1 *> exprAppArg)) + apply l h args + +data Mul = Asterisk | Slash + +mul :: Parser Mul +mul = Asterisk <$ try (string "*") <|> Slash <$ string "/" + +applyMul :: Loc -> Expr -> (Mul, Expr) -> Expr +applyMul l x (Asterisk, y) = Mul l x y +applyMul l x (Slash, y) = Div l x y + +applyListMul :: Loc -> Expr -> [(Mul, Expr)] -> Expr +applyListMul l = foldl' (applyMul l) + +exprMul :: Parser Expr +exprMul = do + l <- getSourcePos + h <- exprApp + args <- many ((,) <$> try (space *> mul) <*> (space *> exprApp)) + pure $ applyListMul l h args + +data Add = Plus | Minus deriving (Show) + +add :: Parser Add +add = Plus <$ try (string "+") <|> Minus <$ string "-" + +applyAdd :: Loc -> Expr -> (Add, Expr) -> Expr +applyAdd l x (Plus, y) = Add l x y +applyAdd l x (Minus, y) = Sub l x y + +applyListAdd :: Loc -> Expr -> [(Add, Expr)] -> Expr +applyListAdd l = foldl' (applyAdd l) + +exprAdd :: Parser Expr +exprAdd = do + l <- getSourcePos + h <- exprMul + args <- many ((,) <$> try (space *> add) <*> (space *> exprMul)) + pure $ applyListAdd l h args + +data Comp = EqSign | NotEqSign | LtSign | LteSign | GtSign | GteSign + +comp :: Parser Comp +comp = EqSign <$ string "==" + <|> NotEqSign <$ string "!=" + <|> LteSign <$ string "<=" + <|> GteSign <$ string ">=" + <|> LtSign <$ string "<" + <|> GtSign <$ string ">" + +applyComp :: Loc -> Expr -> (Comp, Expr) -> Expr +applyComp l a (EqSign, b) = Eq l a b +applyComp l a (NotEqSign, b) = NotEq l a b +applyComp l a (LtSign, b) = Lt l a b +applyComp l a (LteSign, b) = Lte l a b +applyComp l a (GtSign, b) = Gt l a b +applyComp l a (GteSign, b) = Gte l a b + +applyListComp :: Loc -> Expr -> [(Comp, Expr)] -> Expr +applyListComp l = foldl' (applyComp l) + +exprComp :: Parser Expr +exprComp = do + l <- getSourcePos + h <- exprAdd + args <- many ((,) <$> try (space *> comp) <*> (space *> exprAdd)) + pure $ applyListComp l h args + +applyAnd :: Loc -> Expr -> [Expr] -> Expr +applyAnd l = foldl' (And l) + +exprAnd :: Parser Expr +exprAnd = do + l <- getSourcePos + h <- exprComp + args <- many (try (space *> string "&&") *> space *> exprComp) + pure $ applyAnd l h args + +applyOr :: Loc -> Expr -> [Expr] -> Expr +applyOr l = foldl' (Or l) + +exprOr :: Parser Expr +exprOr = do + l <- getSourcePos + h <- exprAnd + args <- many (try (space *> string "||") *> space *> exprAnd) + pure $ applyOr l h args + +exprLet :: Parser Expr +exprLet = do + l <- getSourcePos + void $ string "let" + space1 + x <- variableIdentifier + space + void $ string "=" + space + rhs <- exprOr + space + void $ string "in" + space1 + body <- exprUniverse + pure $ Let l x rhs body + +exprLambda :: Parser Expr +exprLambda = do + l <- getSourcePos + void $ string "\\" + space + x <- variableIdentifier + space + void $ string "->" + space + body <- exprUniverse + pure $ Lambda l x body + +exprUniverse :: Parser Expr +exprUniverse = try exprLet <|> (try exprLambda <|> exprOr) + +expr :: Parser Expr +expr = exprUniverse diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Resolve.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Resolve.hs new file mode 100644 index 00000000000..4df79121150 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Resolve.hs @@ -0,0 +1,119 @@ +module Cardano.Timeseries.Elab.Resolve(resolveTy, resolveBinding, resolveContext, resolveExpr') where +import Cardano.Timeseries.Elab.Typing +import qualified Cardano.Timeseries.Elab.Typing as Ty +import Cardano.Timeseries.Interp.Expr (Expr (..)) +import qualified Cardano.Timeseries.Interp.Expr as Expr + +import qualified Data.Map.Strict as Map + + +-- | Computes the head-normal form of `Ty` w.r.t. hole resolution (i.e. unfolds holes recursively up to the head expression). +resolveTy :: Defs -> Ty -> Ty +resolveTy defs (Ty.Hole x) = + case Map.lookup x defs of + Just (TyHoleInst rhs) -> resolveTy defs rhs + Just _ -> Ty.Hole x + Nothing -> error $ "[INTERNAL ERROR] Can't find hole in Σ: " <> show x +resolveTy defs (InstantVector typ) = InstantVector (resolveTy defs typ) +resolveTy defs (RangeVector typ) = RangeVector (resolveTy defs typ) +resolveTy defs (Fun typ typ') = Fun (resolveTy defs typ) (resolveTy defs typ') +resolveTy defs (Pair typ typ') = Pair (resolveTy defs typ) (resolveTy defs typ') +resolveTy _ Scalar = Scalar +resolveTy _ Timestamp = Timestamp +resolveTy _ Duration = Duration +resolveTy _ Bool = Bool +resolveTy _ Text = Text + +-- | Computes the head-normal form of `Binding` w.r.t. hole resolution +-- (i.e. unfolds holes recursively up to the head expression in type of the binding). +resolveBinding :: Defs -> Binding -> Binding +resolveBinding defs (LetBinding x rhs typ) = + LetBinding x rhs (resolveTy defs typ) +resolveBinding defs (LambdaBinding x typ) = + LambdaBinding x (resolveTy defs typ) + +-- | Computes the head-normal form of `Context` w.r.t. hole resolution +-- (i.e. unfolds holes recursively up to the head expression in every type of the context). +resolveContext :: Defs -> Context -> Context +resolveContext defs = fmap (resolveBinding defs) + + +-- | Computes the normal form of `Expr` w.r.t. hole resolution (i.e. resolves *all* holes in the expression). +resolveExpr' :: Defs -> Expr -> Expr +resolveExpr' _ Metrics = Metrics +resolveExpr' _ (Number f) = Number f +resolveExpr' _ (Str s) = Str s +resolveExpr' defs (AddInstantVectorScalar a b) = AddInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (SubInstantVectorScalar a b) = SubInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (MulInstantVectorScalar a b) = MulInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (DivInstantVectorScalar a b) = DivInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (AddScalar a b) = AddScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (SubScalar a b) = SubScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (MulScalar a b) = MulScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (DivScalar a b) = DivScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (EqScalar a b) = EqScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (NotEqScalar a b) = NotEqScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (LtScalar a b) = LtScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (LteScalar a b) = LteScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (GtScalar a b) = GtScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (GteScalar a b) = GteScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (EqInstantVectorScalar a b) = EqInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (NotEqInstantVectorScalar a b) = NotEqInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (LtInstantVectorScalar a b) = LtInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (LteInstantVectorScalar a b) = LteInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (GtInstantVectorScalar a b) = GtInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (GteInstantVectorScalar a b) = GteInstantVectorScalar (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' _ Expr.True = Expr.True +resolveExpr' _ Expr.False = Expr.False +resolveExpr' defs (Not t) = Not (resolveExpr' defs t) +resolveExpr' defs (And a b) = And (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (Or a b) = Or (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (EqBool a b) = EqBool (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (NotEqBool a b) = NotEqBool (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (LtBool a b) = LtBool (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (LteBool a b) = LteBool (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (GtBool a b) = GtBool (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (GteBool a b) = GteBool (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (Application f e) = Application (resolveExpr' defs f) (resolveExpr' defs e) +resolveExpr' defs (Lambda x f) = Lambda x (resolveExpr' defs f) +resolveExpr' defs (Let x rhs e) = Let x (resolveExpr' defs rhs) (resolveExpr' defs e) +resolveExpr' defs (MkPair a b) = MkPair (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' _ (Variable x) = Variable x +resolveExpr' _ (Milliseconds l) = Milliseconds l +resolveExpr' _ (Seconds l) = Seconds l +resolveExpr' _ (Minutes l) = Minutes l +resolveExpr' _ (Hours l) = Hours l +resolveExpr' defs (AddDuration a b) = AddDuration (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (Rewind a b) = Rewind (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (FastForward a b) = FastForward (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' _ Epoch = Epoch +resolveExpr' _ Now = Now +resolveExpr' defs (DurationToScalar t) = DurationToScalar (resolveExpr' defs t) +resolveExpr' defs (TimestampToScalar t) = TimestampToScalar (resolveExpr' defs t) +resolveExpr' defs (BoolToScalar t) = BoolToScalar (resolveExpr' defs t) +resolveExpr' defs (InstantVectorToScalar t) = InstantVectorToScalar (resolveExpr' defs t) +resolveExpr' defs (Abs t) = Abs (resolveExpr' defs t) +resolveExpr' defs (RoundScalar t) = RoundScalar (resolveExpr' defs t) +resolveExpr' defs (Fst t) = Fst (resolveExpr' defs t) +resolveExpr' defs (Snd t) = Snd (resolveExpr' defs t) +resolveExpr' defs (AvgOverTime t) = AvgOverTime (resolveExpr' defs t) +resolveExpr' defs (SumOverTime t) = SumOverTime (resolveExpr' defs t) +resolveExpr' defs (Avg t) = Avg (resolveExpr' defs t) +resolveExpr' defs (Min t) = Min (resolveExpr' defs t) +resolveExpr' defs (Max t) = Max (resolveExpr' defs t) +resolveExpr' defs (Rate t) = Rate (resolveExpr' defs t) +resolveExpr' defs (Increase t) = Increase (resolveExpr' defs t) +resolveExpr' defs (QuantileOverTime a b) = QuantileOverTime (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (Filter a b) = Filter (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (FilterByLabel a b) = FilterByLabel a (resolveExpr' defs b) +resolveExpr' defs (Join a b) = Join (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (Unless a b) = Unless (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (Map a b) = Map (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (Quantile a b) = Quantile (resolveExpr' defs a) (resolveExpr' defs b) +resolveExpr' defs (Range a b c d) = + Range (resolveExpr' defs a) (resolveExpr' defs b) (resolveExpr' defs c) (resolveExpr' defs <$> d) +resolveExpr' defs (QuantileBy a b c) = QuantileBy a (resolveExpr' defs b) (resolveExpr' defs c) +resolveExpr' defs (Expr.Hole idx) = + case Map.lookup idx defs of + Just (ExprHoleInst rhs _) -> resolveExpr' defs rhs + _ -> Expr.Hole idx diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Typing.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Typing.hs new file mode 100644 index 00000000000..da20972bfad --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Typing.hs @@ -0,0 +1,108 @@ +{-# LANGUAGE FlexibleInstances #-} + +module Cardano.Timeseries.Elab.Typing( + Ty(..), + Binding(..), + Context, + identifier, + Def(..), + Defs, + instantiateTy, + instantiateExpr, + prettyTy, + TyPrec(..), + ty + ) where + +import Cardano.Timeseries.AsText +import Cardano.Timeseries.Domain.Identifier (Identifier) +import Cardano.Timeseries.Interp.Expr (HoleIdentifier) +import qualified Cardano.Timeseries.Interp.Expr as Semantic + +import Data.Foldable as Foldable (toList) +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Sequence as Seq +import Data.Text (Text) +import qualified Data.Text as Text + +-- | Typing of a query expression. +data Ty = InstantVector Ty + | RangeVector Ty + | Scalar + | Text + | Bool + | Pair Ty Ty + | Timestamp + | Duration + | Fun Ty Ty + | Hole HoleIdentifier deriving (Show, Eq) + +data TyPrec = Loose | FunCodomain | FunDomain | Tight deriving (Show, Eq, Ord) + +conditionalParens :: Bool -> Text -> Text +conditionalParens True t = "(" <> t <> ")" +conditionalParens False t = t + +prettyTy :: TyPrec -> Ty -> Text +prettyTy prec (InstantVector typ) = conditionalParens (prec == Tight) $ + "InstantVector " <> prettyTy Tight typ +prettyTy prec (RangeVector typ) = conditionalParens (prec == Tight) $ + "RangeVector " <> prettyTy Tight typ +prettyTy _prec (Pair typ typ') = + "(" <> prettyTy Loose typ <> ", " <> prettyTy Loose typ' <> ")" +prettyTy prec (Fun typ typ') = conditionalParens (prec > FunCodomain) $ + prettyTy FunDomain typ <> " -> " <> prettyTy FunCodomain typ' +prettyTy _ Scalar = "Scalar" +prettyTy _ Bool = "Bool" +prettyTy _ Timestamp = "Timestamp" +prettyTy _ Duration = "Duration" +prettyTy _ Text = "Text" +prettyTy _ (Hole idx) = "?" <> showT idx + +-- | A context entry of a typing context. +data Binding = LetBinding Identifier Semantic.Expr Ty + | LambdaBinding Identifier Ty deriving (Show) + +instance AsText Binding where + asText (LetBinding x _rhs typ) = "(" <> asText x <> " ≔ " <> "..." <> " : " <> prettyTy Loose typ <> ")" + asText (LambdaBinding x typ) = "(" <> asText x <> " : " <> prettyTy Loose typ <> ")" + +identifier :: Binding -> Identifier +identifier (LetBinding x _ _) = x +identifier (LambdaBinding x _) = x + +ty :: Binding -> Ty +ty (LetBinding _ _ typ) = typ +ty (LambdaBinding _ typ) = typ + +-- | Γ +-- A typing context of a query expression. +type Context = Seq Binding + +instance AsText Context where + asText Empty = "()" + asText ctx = Text.unwords $ map asText $ Foldable.toList ctx + +-- | (? type) | (? ≔ T type) | (? : T) | (? ≔ t : T) +-- Definition of a type- or expression- level hole. +data Def = TyHoleDecl | TyHoleInst Ty | ExprHoleDecl Ty | ExprHoleInst Semantic.Expr Ty + +-- | Σ +-- A collection of hole definitions `Def` indexed by `HoleIdentifier`. +type Defs = Map HoleIdentifier Def + +-- | Assumes that the given `Defs` contains a `TyHoleDecl` of the given `HoleIdentifier`. +instantiateTy :: HoleIdentifier -> Ty -> Defs -> Defs +instantiateTy x rhs defs = + case Map.lookup x defs of + Just TyHoleDecl -> Map.insert x (TyHoleInst rhs) defs + _ -> error $ "[INTERNAL ERROR] Incorrect or missing Def for type hole identifier: " <> show x + +-- | Assumes that the given `Defs` contains a `ExprHoleDecl` of the given `HoleIdentifier`. +-- Types of the hole and the provided `Semantic.Expr` must be compatible. +instantiateExpr :: HoleIdentifier -> Semantic.Expr -> Defs -> Defs +instantiateExpr x rhs defs = + case Map.lookup x defs of + Just (ExprHoleDecl typ) -> Map.insert x (ExprHoleInst rhs typ) defs + _ -> error $ "[INTERNAL ERROR] Incorrect or missing Def for expr hole identifier: " <> show x diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Unify.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Unify.hs new file mode 100644 index 00000000000..84b741a9d63 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Elab/Unify.hs @@ -0,0 +1,94 @@ +{- HLINT ignore "Use newtype instead of data" -} +module Cardano.Timeseries.Elab.Unify(UnificationProblem(..), St(..), UnifyM, unify, solve) where +import Cardano.Timeseries.Elab.Expr (Loc) +import Cardano.Timeseries.Elab.Resolve +import Cardano.Timeseries.Elab.Typing (Defs, Ty (..), TyPrec (Loose), instantiateTy, + prettyTy) +import Cardano.Timeseries.Interp.Expr (HoleIdentifier) + +import Control.Monad.Except (ExceptT, throwError) +import Control.Monad.State.Strict (State, get, state) +import Data.Text (Text, pack) +import Text.Megaparsec (sourcePosPretty) + +-- | A = B type +-- An equation between two query types containing holes. +-- Unification is an algorithm of finding unique solutions to such equations. +data UnificationProblem = UnificationProblem { + -- | Source location that induces the unification problem. + loc :: Loc, + lhs :: Ty, + rhs :: Ty +} + +data St = St { + defs :: Defs +} + +type UnifyError = Text + +type UnifyM a = ExceptT UnifyError (State St) a + +updateDefs :: Defs -> St -> St +updateDefs defs (St _) = St defs + +unifyHole :: HoleIdentifier -> Ty -> UnifyM () +unifyHole x rhs = do + occurs x rhs >>= \case + True -> error $ "[INTERNAL ERROR] Occurs check failed for " <> show x <> " and " <> show rhs + False -> state $ \st -> + ((), updateDefs (instantiateTy x rhs (defs st)) st) + +-- | Assume the types are head-neutral (i.e. resolved holes have been substituted in if the hole is the outer expression) +unifyNu :: Loc -> Ty -> Ty -> UnifyM [UnificationProblem] +unifyNu loc (Fun a b) (Fun a' b') = pure [UnificationProblem loc a a', UnificationProblem loc b b'] +unifyNu loc (InstantVector a) (InstantVector a') = pure [UnificationProblem loc a a'] +unifyNu loc (RangeVector a) (RangeVector a') = pure [UnificationProblem loc a a'] +unifyNu _ Scalar Scalar = pure [] +unifyNu _ Bool Bool = pure [] +unifyNu _ Text Text = pure [] +unifyNu _ Timestamp Timestamp = pure [] +unifyNu _ Duration Duration = pure [] +unifyNu loc (Pair a b) (Pair a' b') = pure [UnificationProblem loc a a', UnificationProblem loc b b'] +unifyNu _ (Hole x) (Hole y) | x == y = pure [] +unifyNu _ (Hole x) ty = [] <$ unifyHole x ty +unifyNu _ ty (Hole y) = [] <$ unifyHole y ty +unifyNu loc lhs rhs = + throwError $ "Can't solve unification constraint: " + <> prettyTy Loose lhs + <> " = " + <> prettyTy Loose rhs + <> " @ " + <> pack (sourcePosPretty loc) + +-- | Check if the given hole identifier occurs in the given type. +occurs :: HoleIdentifier -> Ty -> UnifyM Bool +occurs x ty = do + ds <- defs <$> get + occursNu x (resolveTy ds ty) + +-- | `Ty` is assumed to be normal w.r.t. hole substitution. +occursNu :: HoleIdentifier -> Ty -> UnifyM Bool +occursNu x (InstantVector ty) = occursNu x ty +occursNu x (RangeVector ty) = occursNu x ty +occursNu x (Fun ty ty') = (||) <$> occursNu x ty <*> occursNu x ty' +occursNu x (Pair ty ty') = (||) <$> occursNu x ty <*> occursNu x ty' +occursNu _ Scalar = pure False +occursNu _ Bool = pure False +occursNu _ Timestamp = pure False +occursNu _ Duration = pure False +occursNu _ Text = pure False +occursNu x (Hole x') = pure (x == x') + +unify :: Loc -> Ty -> Ty -> UnifyM [UnificationProblem] +unify loc lhs rhs = do + ds <- defs <$> get + unifyNu loc (resolveTy ds lhs) (resolveTy ds rhs) + +-- | Solve the list of unification problems, instantiating holes in the process. +-- If a problem doesn't have a (unique) solution, throw an error. +solve :: [UnificationProblem] -> UnifyM () +solve [] = pure () +solve (UnificationProblem loc lhs rhs : rest) = do + new <- unify loc lhs rhs + solve (new ++ rest) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Import/PlainCBOR.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Import/PlainCBOR.hs new file mode 100644 index 00000000000..87a57291d00 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Import/PlainCBOR.hs @@ -0,0 +1,58 @@ +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE TypeSynonymInstances #-} + +{-# OPTIONS_GHC -Wno-type-defaults -Wno-orphans #-} + +module Cardano.Timeseries.Import.PlainCBOR where + +import Cardano.Timeseries.Domain.Instant (Instant (..)) +import Cardano.Timeseries.Store.Flat (Flat, Point (..)) + +import Codec.Serialise +import Data.Map.Strict as Map (Map) +import qualified Data.Map.Strict as Map +import qualified Data.Set as Set +import Data.Text (Text, unpack) +import Data.Time.Clock.POSIX (POSIXTime) +import GHC.Generics (Generic) + + +data NumericValue = + NVInt Int + | NVDouble Double + deriving (Generic, Show, Serialise) + + +data Snapshot = Snapshot + { singletonLabel :: Text + , timeStamp :: POSIXTime + , scrape :: Map Text NumericValue + } + deriving (Generic, Serialise) + +instance Show Snapshot where + show (Snapshot l t s) = "Snapshot{" ++ unpack l ++ "} @ " ++ show t ++ ", entries: " ++ show s + + +instance Serialise POSIXTime where + encode = encode . toInteger . floor + decode = fromInteger <$> decode + + +readFileSnapshots :: FilePath -> IO [Snapshot] +readFileSnapshots = readFileDeserialise + +numericValueToDouble :: NumericValue -> Double +numericValueToDouble (NVInt x) = fromIntegral x +numericValueToDouble (NVDouble x) = x + +scrapeDatapointToPoint :: Text -> POSIXTime -> Text -> NumericValue -> Point Double +scrapeDatapointToPoint node t metric v = + Point metric (Instant (Set.fromList [("node", node)]) (floor (t * 1000)) (numericValueToDouble v)) + +snapshotToFlatStore :: Snapshot -> Flat Double +snapshotToFlatStore (Snapshot l t s) = Map.foldlWithKey' (\acc k v -> scrapeDatapointToPoint l t k v : acc) [] s + +snapshotsToFlatStore :: [Snapshot] -> Flat Double +snapshotsToFlatStore = (>>= snapshotToFlatStore) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp.hs new file mode 100644 index 00000000000..050657fdf1f --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp.hs @@ -0,0 +1,365 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE ViewPatterns #-} + +module Cardano.Timeseries.Interp(interp) where +import Cardano.Timeseries.AsText (showT) +import Cardano.Timeseries.Domain.Identifier (Identifier (..)) +import Cardano.Timeseries.Domain.Instant (Instant (Instant), InstantVector, share) +import qualified Cardano.Timeseries.Domain.Instant as Domain +import qualified Cardano.Timeseries.Domain.Instant as Instant +import Cardano.Timeseries.Domain.Interval +import Cardano.Timeseries.Domain.Timeseries (TimeseriesVector, eachNewest, eachOldest, + superseries, transpose) +import Cardano.Timeseries.Domain.Types (Label, Labelled, MetricIdentifier, Timestamp) +import Cardano.Timeseries.Interp.Config (Config (..)) +import Cardano.Timeseries.Interp.Expect +import Cardano.Timeseries.Interp.Statistics +import Cardano.Timeseries.Interp.Types +import Cardano.Timeseries.Interp.Value as Value +import Cardano.Timeseries.Interp.BinaryArithmeticOp (BinaryArithmeticOp) +import qualified Cardano.Timeseries.Interp.BinaryArithmeticOp as BinaryArithmeticOp +import Cardano.Timeseries.Interp.BinaryRelation (BinaryRelation, embedScalar, + mbBinaryRelationInstantVector, mbBinaryRelationScalar) +import qualified Cardano.Timeseries.Interp.BinaryRelation as BinaryRelation +import Cardano.Timeseries.Interp.Expr as Expr +import Cardano.Timeseries.Store (Store (metrics)) +import qualified Cardano.Timeseries.Store as Store +import Cardano.Timeseries.Util (maybeToEither) + +import Prelude hiding (max, min, pred) + +import Control.Monad (filterM, (<=<)) +import Control.Monad.Except (liftEither) +import Control.Monad.State (get, put) +import Control.Monad.Trans (lift) +import Data.Function (on) +import Data.List (find, groupBy) +import qualified Data.List as List +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Maybe (fromMaybe) +import Data.Set (Set, isSubsetOf, member) +import qualified Data.Set as Set +import Data.Text (Text) +import Data.Word (Word64) + +import Statistics.Function (minMax) +import Statistics.Quantile (cadpw, quantile) +import Statistics.Sample (mean) +import qualified Data.Text as Text + + +interpJoin :: (a -> b -> c) -> InstantVector a -> InstantVector b -> Either InterpError (InstantVector c) +interpJoin _ [] _ = Right [] +interpJoin f (inst@(Domain.Instant ls t v) : xs) other = do + Domain.Instant _ _ v' <- maybeToEither (InterpError $ "No matching label: " <> showT ls) $ find (share inst) other + rest <- interpJoin f xs other + Right (Domain.Instant ls t (f v v') : rest) + +interpRange :: FunctionValue -> Interval -> Word64 -> InterpM (TimeseriesVector Value) +interpRange f Interval{..} rate = transpose <$> sample start end where + + sample :: Timestamp -> Timestamp -> InterpM [InstantVector Value] + sample t max | t > max = pure [] + sample t max = (:) <$> (expectInstantVector <=< f) (Value.Timestamp t) <*> sample (t + rate) max + +interpLabelInst :: LabelConstraint -> Labelled (Bool, Text) +interpLabelInst (LabelConstraintEq (k, v)) = (k, (Prelude.True, v)) +interpLabelInst (LabelConstraintNotEq (k, v)) = (k, (Prelude.False, v)) + +interpLabelInsts :: Set LabelConstraint -> (Set (Labelled Text), Set (Labelled Text)) +interpLabelInsts ls = + let (sub, notsub) = List.partition cond $ fmap interpLabelInst (Set.toList ls) in + (Set.fromList $ fmap extract sub, Set.fromList $ fmap extract notsub) where + cond (_, (b, _)) = b + extract (x, (_, y)) = (x, y) + +interpVariable :: Store s Double => s -> MetricIdentifier -> Value -> InterpM Value +interpVariable store x t_ = do + t <- expectTimestamp t_ + pure (Value.InstantVector (fmap (fmap Value.Scalar) (Store.evaluate store x t))) + +interpQuantileBy :: Set Label -> Double -> InstantVector Double -> Timestamp -> InterpM (InstantVector Double) +interpQuantileBy ls k vs now = + let groups = groupBy (on (==) (superseries ls . (.labels))) vs + quantiles = fmap (\g -> (superseries ls (head g).labels, quantile cadpw (floor (k * 100)) 100 (Instant.toVector g))) + groups in + pure $ fmap (\(idx, v) -> Instant idx now v) quantiles + +interpFilter :: FunctionValue -> InstantVector Value -> InterpM (InstantVector Value) +interpFilter f = filterM pred where + pred :: Instant Value -> InterpM Bool + pred inst = (expectBoolean <=< f) inst.value + +interpMap :: FunctionValue -> InstantVector Value -> InterpM (InstantVector Value) +interpMap f = traverse (traverse f) + +interpRate :: TimeseriesVector Double -> InterpM (InstantVector Double) +interpRate v = do + min <- liftEither $ maybeToEither (InterpError "Can't compute rate") (eachOldest v) + max <- liftEither $ maybeToEither (InterpError "Can't compute rate") (eachNewest v) + pure $ zipWith compute min max where + + compute :: Instant Double -> Instant Double -> Instant Double + compute min max = + let x = (max.value - min.value) / fromIntegral (max.timestamp - min.timestamp) in + Instant min.labels max.timestamp x + +interpIncrease :: TimeseriesVector Double -> InterpM (InstantVector Double) +interpIncrease v = liftEither $ do + min <- maybeToEither (InterpError "Can't compute rate") (eachOldest v) + max <- maybeToEither (InterpError "Can't compute rate") (eachNewest v) + Right $ zipWith compute min max where + + compute :: Instant Double -> Instant Double -> Instant Double + compute min max = + let x = max.value - min.value in + Instant min.labels max.timestamp x + +-- | (v `op` s) ≡ map (\x -> x `op` s) v +-- | where v : InstantVector Scalar +-- | s : Scalar +interpBinaryArithmeticOp :: Store s Double + => Config + -> s + -> Map Identifier Value + -> Expr + -> BinaryArithmeticOp + -> Expr + -> Timestamp + -> InterpM Value +interpBinaryArithmeticOp cfg store env v op k now = do + nextVarIdx <- lift get + lift (put (1 + nextVarIdx)) + interp cfg store env + (Map + ( + Lambda + (Machine nextVarIdx) + (BinaryArithmeticOp.embedScalar op (Variable (Machine nextVarIdx)) k) + ) + v + ) + now + +-- | (v `R` s) ≡ filter (\x -> x `R` s) v +-- | where v : InstantVector Scalar +-- | s : Scalar +interpFilterBinaryRelation :: Store s Double + => Config + -> s + -> Map Identifier Value + -> Expr + -> BinaryRelation + -> Expr + -> Timestamp + -> InterpM Value +interpFilterBinaryRelation cfg store env v rel k now = do + nextVarIdx <- lift get + lift (put (1 + nextVarIdx)) + interp cfg store env + (Filter + ( + Lambda + (Machine nextVarIdx) + (embedScalar rel (Variable (Machine nextVarIdx)) k) + ) + v + ) + now + +-- | Given a metric store, an assignment of values to local variables, a query expression and a timestamp "now", +-- interpret the `Expr` into a `Value`. +interp :: Store s Double => Config -> s -> Map Identifier Value -> Expr -> Timestamp -> InterpM Value +interp _ store _ Expr.Metrics _ = do + pure $ Value.Text $ Text.intercalate ", " (Set.toList $ metrics store) +interp _ _ _ (Expr.Number x) _ = do + pure (Value.Scalar x) +interp _ store env (Expr.Variable x) _ = + case Map.lookup x env of + Just v -> pure v + Nothing -> + case x of + User u | member u (metrics store) -> + pure $ Value.Function (interpVariable store u) + _ -> + throwInterpError $ "Undefined variable: " <> showT x +interp _ _ _ Now now = pure (Timestamp (fromIntegral now)) +interp _ _ _ Epoch _ = pure (Timestamp 0) +interp cfg store env (Lambda x body) now = pure $ Value.Function $ \v -> + interp cfg store (Map.insert x v env) body now +interp cfg store env (Let x rhs body) now = do + v <- interp cfg store env rhs now + interp cfg store (Map.insert x v env) body now +interp cfg store env (FastForward t_ d_) now = do + t <- interp cfg store env t_ now >>= expectTimestamp + d <- interp cfg store env d_ now >>= expectDuration + pure (Value.Timestamp (t + d)) +interp cfg store env (FilterByLabel cs s_) now = do + s <- interp cfg store env s_ now >>= expectInstantVector + let (mustBe, mustNotBe) = interpLabelInsts cs + pure $ + Value.InstantVector $ + flip filter s $ \i -> + (&&) + (mustBe `isSubsetOf` i.labels) + (Set.null (mustNotBe `Set.intersection` i.labels)) +interp cfg store env (Unless u_ v_) now = do + u <- interp cfg store env u_ now >>= expectInstantVector + v <- interp cfg store env v_ now >>= expectInstantVector + let vls = Set.fromList (map (.labels) v) + pure (Value.InstantVector (filter (\i -> not (member i.labels vls)) u)) +interp cfg store env (Filter f_ t_) now = do + f <- interp cfg store env f_ now >>= expectFunction + t <- interp cfg store env t_ now >>= expectInstantVector + Value.InstantVector <$> interpFilter f t +interp cfg store env (Join a_ b_) now = do + a <- interp cfg store env a_ now >>= expectInstantVector + b <- interp cfg store env b_ now >>= expectInstantVector + Value.InstantVector <$> liftEither (interpJoin Value.Pair a b) +interp cfg store env (Map f_ x_) now = do + f <- interp cfg store env f_ now >>= expectFunction + x <- interp cfg store env x_ now >>= expectInstantVector + Value.InstantVector <$> interpMap f x +interp cfg store env (Range s_ a_ b_ r_) now = do + s <- interp cfg store env s_ now >>= expectFunction + a <- interp cfg store env a_ now >>= expectTimestamp + b <- interp cfg store env b_ now >>= expectTimestamp + r <- traverse (\r' -> interp cfg store env r' now >>= expectDuration) r_ + RangeVector <$> interpRange s (Interval a b) (fromMaybe cfg.defaultRangeSamplingRateMillis r) +interp cfg store env (Rewind t_ d_) now = do + t <- interp cfg store env t_ now >>= expectTimestamp + d <- interp cfg store env d_ now >>= expectDuration + pure (Timestamp (t - d)) +interp cfg store env (BoolToScalar t_) now = do + t <- interp cfg store env t_ now >>= expectBoolean + pure (Scalar (if t then 1 else 0)) +interp cfg store env (InstantVectorToScalar t_) now = do + t <- interp cfg store env t_ now >>= expectInstantVectorBool + pure (Value.InstantVector (fmap (\x -> Value.Scalar (if x then 1.0 else 0.0)) <$> t)) +interp cfg store env (TimestampToScalar t_) now = do + t <- interp cfg store env t_ now >>= expectTimestamp + pure (Scalar (fromIntegral t)) +interp cfg store env (DurationToScalar t_) now = do + t <- interp cfg store env t_ now >>= expectDuration + pure (Scalar (fromIntegral t)) +interp _ _ _ (Milliseconds t) _ = pure $ Duration t +interp _ _ _ (Seconds t) _ = pure $ Duration (1000 * t) +interp _ _ _ (Minutes t) _ = pure $ Duration (60 * 1000 * t) +interp _ _ _ (Hours t) _ = pure $ Duration (60 * 60 * 1000 * t) +interp cfg store env (BinaryArithmeticOp.mbBinaryArithmeticOpInstantVectorScalar -> Just (v, op, k)) now = do + interpBinaryArithmeticOp cfg store env v op k now +interp cfg store env (Quantile k_ expr) now = do + k <- interp cfg store env k_ now >>= expectScalar + v <- interp cfg store env expr now >>= expectInstantVectorScalar + pure $ Value.Scalar $ quantile cadpw (floor (k * 100)) 100 (Instant.toVector v) +interp cfg store env (QuantileBy ls k_ expr) now = do + k <- interp cfg store env k_ now >>= expectScalar + v <- interp cfg store env expr now >>= expectInstantVectorScalar + Value.InstantVector . fmap (fmap Value.Scalar) <$> interpQuantileBy ls k v now +interp cfg store env (QuantileOverTime k_ expr) now = do + k <- interp cfg store env k_ now >>= expectScalar + v <- interp cfg store env expr now >>= expectRangeVectorScalar + pure $ Value.InstantVector (fmap Value.Scalar <$> quantileRangeVector k v) +interp cfg store env (Rate r_) now = do + r <- interp cfg store env r_ now >>= expectRangeVectorScalar + -- TODO: PromQL's rate() performs linear regression to extrapolate the samples to the bounds + r' <- interpRate r + pure (Value.InstantVector (fmap (fmap Value.Scalar) r')) +interp cfg store env (Increase r_) now = do + r <- interp cfg store env r_ now >>= expectRangeVectorScalar + -- TODO: PromQL's increase() performs linear regression to extrapolate the samples to the bounds + r' <- interpIncrease r + pure (Value.InstantVector (fmap (fmap Value.Scalar) r')) +interp cfg store env (Avg expr) now = do + v <- interp cfg store env expr now >>= expectInstantVectorScalar + pure $ Value.Scalar $ mean (Instant.toVector v) +interp cfg store env (Max expr) now = do + v <- interp cfg store env expr now >>= expectInstantVectorScalar + pure $ Value.Scalar $ snd $ minMax (Instant.toVector v) +interp cfg store env (Min expr) now = do + v <- interp cfg store env expr now >>= expectInstantVectorScalar + pure $ Value.Scalar $ fst $ minMax (Instant.toVector v) +interp cfg store env (AvgOverTime expr) now = do + v <- interp cfg store env expr now >>= expectRangeVectorScalar + pure $ Value.InstantVector (fmap Value.Scalar <$> avgOverTime now v) +interp cfg store env (SumOverTime expr) now = do + v <- interp cfg store env expr now >>= expectRangeVectorScalar + pure $ Value.InstantVector (fmap Value.Scalar <$> sumOverTime now v) +interp cfg store env (MkPair a b) now = do + va <- interp cfg store env a now + vb <- interp cfg store env b now + pure $ Value.Pair va vb +interp cfg store env (Fst t) now = do + (a, _) <- interp cfg store env t now >>= expectPair + pure a +interp cfg store env (Snd t) now = do + (_, b) <- interp cfg store env t now >>= expectPair + pure b +interp _ _ _ Expr.True _ = do + pure Truth +interp _ _ _ Expr.False _ = do + pure Falsity +interp cfg store env (Expr.And a b) now = do + va <- interp cfg store env a now >>= expectBoolean + vb <- interp cfg store env b now >>= expectBoolean + pure (fromBool (va && vb)) +interp cfg store env (Expr.Or a b) now = do + va <- interp cfg store env a now >>= expectBoolean + vb <- interp cfg store env b now >>= expectBoolean + pure (fromBool (va || vb)) +interp cfg store env (Expr.Not t_) now = do + vt <- interp cfg store env t_ now >>= expectBoolean + pure (fromBool (not vt)) +interp cfg store env (Expr.EqBool a b) now = do + va <- interp cfg store env a now >>= expectBoolean + vb <- interp cfg store env b now >>= expectBoolean + pure (fromBool (va == vb)) +interp cfg store env (Expr.NotEqBool a b) now = do + va <- interp cfg store env a now >>= expectBoolean + vb <- interp cfg store env b now >>= expectBoolean + pure (fromBool (va /= vb)) +interp cfg store env (Expr.LtBool a b) now = do + va <- interp cfg store env a now >>= expectBoolean + vb <- interp cfg store env b now >>= expectBoolean + pure (fromBool (va < vb)) +interp cfg store env (Expr.LteBool a b) now = do + va <- interp cfg store env a now >>= expectBoolean + vb <- interp cfg store env b now >>= expectBoolean + pure (fromBool (va <= vb)) +interp cfg store env (Expr.GtBool a b) now = do + va <- interp cfg store env a now >>= expectBoolean + vb <- interp cfg store env b now >>= expectBoolean + pure (fromBool (va > vb)) +interp cfg store env (Expr.GteBool a b) now = do + va <- interp cfg store env a now >>= expectBoolean + vb <- interp cfg store env b now >>= expectBoolean + pure (fromBool (va >= vb)) +interp cfg store env (mbBinaryRelationScalar -> Just (a, rel, b)) now = do + va <- interp cfg store env a now >>= expectScalar + vb <- interp cfg store env b now >>= expectScalar + pure (fromBool (BinaryRelation.materializeScalar rel va vb)) +interp cfg store env (BinaryArithmeticOp.mbBinaryArithmeticOpScalar -> Just (a, op, b)) now = do + va <- interp cfg store env a now >>= expectScalar + vb <- interp cfg store env b now >>= expectScalar + pure (Value.Scalar (BinaryArithmeticOp.materializeScalar op va vb)) +interp cfg store env (Expr.Abs x_) now = do + x <- interp cfg store env x_ now >>= expectScalar + pure (Value.Scalar (abs x)) +interp cfg store env (Expr.RoundScalar x_) now = do + x <- interp cfg store env x_ now >>= expectScalar + pure (Value.Scalar (fromIntegral (round x :: Int))) +interp cfg store env (Application f_ e_) now = do + f <- interp cfg store env f_ now >>= expectFunction + e <- interp cfg store env e_ now + f e +interp cfg store env (Expr.AddDuration a_ b_) now = do + a <- interp cfg store env a_ now >>= expectDuration + b <- interp cfg store env b_ now >>= expectDuration + pure (Value.Duration (a + b)) +interp cfg store env (mbBinaryRelationInstantVector -> Just (v, rel, k)) now = + interpFilterBinaryRelation cfg store env v rel k now +interp _ _ _ expr _ = throwInterpError $ "Can't interpret expression: " <> showT expr diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/BinaryArithmeticOp.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/BinaryArithmeticOp.hs new file mode 100644 index 00000000000..a2821b8b935 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/BinaryArithmeticOp.hs @@ -0,0 +1,47 @@ +module Cardano.Timeseries.Interp.BinaryArithmeticOp(BinaryArithmeticOp(..), + embedScalar, embedInstantVectorScalar, + mbBinaryArithmeticOpScalar, mbBinaryArithmeticOpInstantVectorScalar, materializeScalar) where + +import Cardano.Timeseries.AsText +import Cardano.Timeseries.Interp.Expr (Expr (..)) + +data BinaryArithmeticOp = Add | Sub | Mul | Div deriving (Show, Eq, Ord) + +instance AsText BinaryArithmeticOp where + asText = \case + Add -> "+" + Sub -> "-" + Mul -> "*" + Div -> "/" + +embedScalar :: BinaryArithmeticOp -> Expr -> Expr -> Expr +embedScalar Add = AddScalar +embedScalar Sub = SubScalar +embedScalar Mul = MulScalar +embedScalar Div = DivScalar + +embedInstantVectorScalar :: BinaryArithmeticOp -> Expr -> Expr -> Expr +embedInstantVectorScalar Add = AddInstantVectorScalar +embedInstantVectorScalar Sub = SubInstantVectorScalar +embedInstantVectorScalar Mul = MulInstantVectorScalar +embedInstantVectorScalar Div = DivInstantVectorScalar + +mbBinaryArithmeticOpInstantVectorScalar :: Expr -> Maybe (Expr, BinaryArithmeticOp, Expr) +mbBinaryArithmeticOpInstantVectorScalar (AddInstantVectorScalar a b) = Just (a, Add, b) +mbBinaryArithmeticOpInstantVectorScalar (SubInstantVectorScalar a b) = Just (a, Sub, b) +mbBinaryArithmeticOpInstantVectorScalar (MulInstantVectorScalar a b) = Just (a, Mul, b) +mbBinaryArithmeticOpInstantVectorScalar (DivInstantVectorScalar a b) = Just (a, Div, b) +mbBinaryArithmeticOpInstantVectorScalar _ = Nothing + +mbBinaryArithmeticOpScalar :: Expr -> Maybe (Expr, BinaryArithmeticOp, Expr) +mbBinaryArithmeticOpScalar (AddScalar a b) = Just (a, Add, b) +mbBinaryArithmeticOpScalar (SubScalar a b) = Just (a, Sub, b) +mbBinaryArithmeticOpScalar (MulScalar a b) = Just (a, Mul, b) +mbBinaryArithmeticOpScalar (DivScalar a b) = Just (a, Div, b) +mbBinaryArithmeticOpScalar _ = Nothing + +materializeScalar :: BinaryArithmeticOp -> Double -> Double -> Double +materializeScalar Add = (+) +materializeScalar Sub = (-) +materializeScalar Mul = (*) +materializeScalar Div = (/) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/BinaryRelation.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/BinaryRelation.hs new file mode 100644 index 00000000000..3a276b1ec90 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/BinaryRelation.hs @@ -0,0 +1,88 @@ +module Cardano.Timeseries.Interp.BinaryRelation( + BinaryRelation(..), + embedScalar, + embedBool, + embedInstantVectorScalar, + mbBinaryRelationInstantVector, + mbBinaryRelationScalar, + swapInstantVectorScalar, + materializeScalar) where + +import Cardano.Timeseries.AsText +import Cardano.Timeseries.Interp.Expr (Expr (..)) + +-- | A datatype used to carve out a subset of `Function` that represents binary relations. +data BinaryRelation = Eq | Lt | Lte | Gt | Gte | NotEq deriving (Show, Eq, Ord) + +instance AsText BinaryRelation where + asText = \case + Eq -> "==" + Lt -> "<" + Lte -> "<=" + Gt -> ">" + Gte -> ">=" + NotEq -> "!=" + +embedScalar :: BinaryRelation -> Expr -> Expr -> Expr +embedScalar Eq = EqScalar +embedScalar Lt = LtScalar +embedScalar Lte = LteScalar +embedScalar Gt = GtScalar +embedScalar Gte = GteScalar +embedScalar NotEq = NotEqScalar + +embedBool :: BinaryRelation -> Expr -> Expr -> Expr +embedBool Eq = EqBool +embedBool Lt = LtBool +embedBool Lte = LteBool +embedBool Gt = GtBool +embedBool Gte = GteBool +embedBool NotEq = NotEqBool + +embedInstantVectorScalar :: BinaryRelation -> Expr -> Expr -> Expr +embedInstantVectorScalar Eq = EqInstantVectorScalar +embedInstantVectorScalar Lt = LtInstantVectorScalar +embedInstantVectorScalar Lte = LteInstantVectorScalar +embedInstantVectorScalar Gt = GtInstantVectorScalar +embedInstantVectorScalar Gte = GteInstantVectorScalar +embedInstantVectorScalar NotEq = NotEqInstantVectorScalar + +-- k < v <=> v > k +-- k ≤ v <=> v ≥ k +-- k > v <=> v < k +-- k ≥ v <=> v ≤ k +-- k = v <=> v = k +-- k ≠ v <=> v ≠ k +swapInstantVectorScalar :: BinaryRelation -> BinaryRelation +swapInstantVectorScalar Eq = Eq +swapInstantVectorScalar NotEq = NotEq +swapInstantVectorScalar Lt = Gt +swapInstantVectorScalar Lte = Gte +swapInstantVectorScalar Gt = Lt +swapInstantVectorScalar Gte = Lte + +mbBinaryRelationInstantVector :: Expr -> Maybe (Expr, BinaryRelation, Expr) +mbBinaryRelationInstantVector (EqInstantVectorScalar a b) = Just (a, Eq, b) +mbBinaryRelationInstantVector (LtInstantVectorScalar a b) = Just (a, Lt, b) +mbBinaryRelationInstantVector (LteInstantVectorScalar a b) = Just (a, Lte, b) +mbBinaryRelationInstantVector (GtInstantVectorScalar a b) = Just (a, Gt, b) +mbBinaryRelationInstantVector (GteInstantVectorScalar a b) = Just (a, Gte, b) +mbBinaryRelationInstantVector (NotEqInstantVectorScalar a b) = Just (a, NotEq, b) +mbBinaryRelationInstantVector _ = Nothing + +mbBinaryRelationScalar :: Expr -> Maybe (Expr, BinaryRelation, Expr) +mbBinaryRelationScalar (EqScalar a b) = Just (a, Eq, b) +mbBinaryRelationScalar (LtScalar a b) = Just (a, Lt, b) +mbBinaryRelationScalar (LteScalar a b) = Just (a, Lte, b) +mbBinaryRelationScalar (GtScalar a b) = Just (a, Gt, b) +mbBinaryRelationScalar (GteScalar a b) = Just (a, Gte, b) +mbBinaryRelationScalar (NotEqScalar a b) = Just (a, NotEq, b) +mbBinaryRelationScalar _ = Nothing + +materializeScalar :: BinaryRelation -> Double -> Double -> Bool +materializeScalar Eq = (==) +materializeScalar Lt = (<) +materializeScalar Lte = (<=) +materializeScalar Gt = (>) +materializeScalar Gte = (>=) +materializeScalar NotEq = (/=) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Config.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Config.hs new file mode 100644 index 00000000000..b7b8c6e722d --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Config.hs @@ -0,0 +1,12 @@ +{- HLINT ignore "Use newtype instead of data" -} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} + +module Cardano.Timeseries.Interp.Config where +import Data.Aeson (ToJSON) +import Data.Word (Word64) +import GHC.Generics + +data Config = Config { + defaultRangeSamplingRateMillis :: Word64 +} deriving (Show, Eq, Generic, ToJSON) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Expect.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Expect.hs new file mode 100644 index 00000000000..19bbee2547e --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Expect.hs @@ -0,0 +1,72 @@ +module Cardano.Timeseries.Interp.Expect where + +import Cardano.Timeseries.AsText (showT) +import Cardano.Timeseries.Domain.Instant (Instant, InstantVector) +import Cardano.Timeseries.Domain.Timeseries (Timeseries, TimeseriesVector) +import Cardano.Timeseries.Interp.Types +import Cardano.Timeseries.Interp.Value as Value + +import Data.Word (Word64) + +expectInstantVector :: Value -> InterpM (InstantVector Value) +expectInstantVector (Value.InstantVector v) = pure v +expectInstantVector _ = throwInterpError "Unexpected expression type: expected an instant vector" + +expectRangeVector :: Value -> InterpM (TimeseriesVector Value) +expectRangeVector (Value.RangeVector v) = pure v +expectRangeVector _ = throwInterpError "Unexpected expression type: expected a range vector" + +expectTimeseriesScalar :: Timeseries Value -> InterpM (Timeseries Double) +expectTimeseriesScalar = traverse expectScalar + +expectRangeVectorScalar :: Value -> InterpM (TimeseriesVector Double) +expectRangeVectorScalar v = expectRangeVector v >>= traverse expectTimeseriesScalar + +expectInstantScalar :: Instant Value -> InterpM (Instant Double) +expectInstantScalar = traverse expectScalar + +expectInstantBool :: Instant Value -> InterpM (Instant Bool) +expectInstantBool = traverse expectBool + +expectInstantVectorScalar :: Value -> InterpM (InstantVector Double) +expectInstantVectorScalar v = expectInstantVector v >>= traverse expectInstantScalar + +expectInstantVectorBool :: Value -> InterpM (InstantVector Bool) +expectInstantVectorBool v = expectInstantVector v >>= traverse expectInstantBool + +expectPair :: Value -> InterpM (Value, Value) +expectPair (Value.Pair a b) = pure (a, b) +expectPair _ = throwInterpError "Unexpected expression type: expected a pair" + +expectScalar :: Value -> InterpM Double +expectScalar (Value.Scalar x) = pure x +expectScalar _ = throwInterpError "Unexpected expression type: expected a scalar" + +expectBool :: Value -> InterpM Bool +expectBool Value.Truth = pure Prelude.True +expectBool Value.Falsity = pure Prelude.False +expectBool _ = throwInterpError "Unexpected expression type: expected a bool" + +expectBoolean :: Value -> InterpM Bool +expectBoolean Truth = pure Prelude.True +expectBoolean Falsity = pure Prelude.False +expectBoolean _ = throwInterpError "Unexpected expression type: expected a boolean" + +expectDuration :: Value -> InterpM Word64 +expectDuration (Value.Duration x) = pure x +expectDuration _ = throwInterpError "Unexpected expression type: expected a duration" + +expectTimestamp :: Value -> InterpM Word64 +expectTimestamp (Value.Timestamp x) = pure x +expectTimestamp _ = throwInterpError "Unexpected expression type: expected a timestamp" + +expectFunction :: Value -> InterpM FunctionValue +expectFunction (Value.Function f) = pure f +expectFunction _ = throwInterpError "Unexpected expression type: expected a function" + +expectWord64 :: Double -> InterpM Word64 +expectWord64 x + | snd pf == 0.0 = pure $ fst pf + | otherwise = throwInterpError $ "Expected a whole number, got: " <> showT x + where + pf = properFraction x diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Expr.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Expr.hs new file mode 100644 index 00000000000..eec8fe411c1 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Expr.hs @@ -0,0 +1,103 @@ +module Cardano.Timeseries.Interp.Expr(HoleIdentifier, LabelConstraint(..), Expr(..)) where +import Cardano.Timeseries.Domain.Identifier (Identifier) +import Cardano.Timeseries.Domain.Types (Label, Labelled) + +import Data.Set (Set) +import Data.Text (Text) +import Data.Word (Word64) + +type HoleIdentifier = Int + +data LabelConstraint = LabelConstraintEq (Labelled Text) | LabelConstraintNotEq (Labelled Text) + deriving (Show, Eq, Ord) + +-- | This expression has the following property, assumed in the interpreter: +-- | every expression can be given at most one type and can have at most one interpretation. +-- | The property essentially means that expressions like (a + b) can't be part of the language unless +-- | `+` has only one possible meaning, which is not that case (It can be addition of scalars and addition of instant vectors) +data Expr = Number Double + | Variable Identifier + | Str String + | Application Expr Expr + | Lambda Identifier Expr + | Let Identifier Expr Expr + + | AddInstantVectorScalar Expr Expr + | SubInstantVectorScalar Expr Expr + | MulInstantVectorScalar Expr Expr + | DivInstantVectorScalar Expr Expr + | EqInstantVectorScalar Expr Expr + | LtInstantVectorScalar Expr Expr + | LteInstantVectorScalar Expr Expr + | GtInstantVectorScalar Expr Expr + | GteInstantVectorScalar Expr Expr + | NotEqInstantVectorScalar Expr Expr + + | True + | False + | And Expr Expr + | Or Expr Expr + | Not Expr + | EqBool Expr Expr + | NotEqBool Expr Expr + | LtBool Expr Expr + | LteBool Expr Expr + | GtBool Expr Expr + | GteBool Expr Expr + + | Milliseconds Word64 + | Seconds Word64 + | Minutes Word64 + | Hours Word64 + | DurationToScalar Expr + | AddDuration Expr Expr + | Now + | Epoch + | Rewind Expr Expr + | FastForward Expr Expr + | TimestampToScalar Expr + + | AddScalar Expr Expr + | SubScalar Expr Expr + | MulScalar Expr Expr + | DivScalar Expr Expr + | EqScalar Expr Expr + | LtScalar Expr Expr + | LteScalar Expr Expr + | GtScalar Expr Expr + | GteScalar Expr Expr + | NotEqScalar Expr Expr + | BoolToScalar Expr + | InstantVectorToScalar Expr + | Abs Expr + | RoundScalar Expr + + | MkPair Expr Expr + | Fst Expr + | Snd Expr + + | AvgOverTime Expr + | SumOverTime Expr + | Avg Expr + | QuantileBy (Set Label) Expr Expr + | Quantile Expr Expr + | Max Expr + | Min Expr + | Rate Expr + | Increase Expr + | QuantileOverTime Expr Expr + + + | Filter Expr Expr + | Map Expr Expr + | Join Expr Expr + + | Range Expr Expr Expr (Maybe Expr) + + | Unless Expr Expr + + | FilterByLabel (Set LabelConstraint) Expr + + | Metrics + + | Hole HoleIdentifier deriving Show diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Statistics.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Statistics.hs new file mode 100644 index 00000000000..a15757b0820 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Statistics.hs @@ -0,0 +1,31 @@ +{-# LANGUAGE RecordWildCards #-} +module Cardano.Timeseries.Interp.Statistics where +import Cardano.Timeseries.Domain.Instant +import qualified Cardano.Timeseries.Domain.Instant as Domain +import qualified Cardano.Timeseries.Domain.Instant as Instant +import Cardano.Timeseries.Domain.Timeseries +import qualified Cardano.Timeseries.Domain.Timeseries as Timeseries +import Cardano.Timeseries.Domain.Types + +import Data.Maybe (fromJust) + +import Statistics.Quantile (cadpw, quantile) +import Statistics.Sample (mean) + +avgOverTime :: Timestamp -> TimeseriesVector Double -> InstantVector Double +avgOverTime at = fmap compute where + compute :: Timeseries Double -> Instant Double + compute series = Domain.Instant (Timeseries.labels series) at (mean $ Timeseries.toVector series) + +sumOverTime :: Timestamp -> TimeseriesVector Double -> InstantVector Double +sumOverTime at = fmap compute where + compute :: Timeseries Double -> Instant Double + compute series = Domain.Instant (Timeseries.labels series) at (sum $ Timeseries.toVector series) + +quantileTimeseries :: Double -> Timeseries Double -> Instant Double +quantileTimeseries k v@Timeseries{..} = + let value = quantile cadpw (floor (k * 100)) 100 (Timeseries.toVector v) in + Instant labels (Instant.timestamp $ fromJust (Timeseries.newest v)) value + +quantileRangeVector :: Double -> TimeseriesVector Double -> InstantVector Double +quantileRangeVector k = map (quantileTimeseries k) diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Types.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Types.hs new file mode 100644 index 00000000000..70b97629f77 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Types.hs @@ -0,0 +1,16 @@ +module Cardano.Timeseries.Interp.Types where +import Control.Monad.Except (ExceptT, throwError) +import Control.Monad.State.Strict (State) +import Cardano.Timeseries.AsText +import Data.Text (Text) + +newtype InterpError = + InterpError { message :: Text } + +instance AsText InterpError where + asText InterpError{message} = "Interpretation error: " <> message + +type InterpM a = ExceptT InterpError (State Int) a + +throwInterpError :: Text -> InterpM a +throwInterpError = throwError . InterpError diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Value.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Value.hs new file mode 100644 index 00000000000..10661368366 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Interp/Value.hs @@ -0,0 +1,57 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE GADTs #-} + +module Cardano.Timeseries.Interp.Value(Value(..), FunctionValue, fromBool) where + +import Cardano.Timeseries.AsText +import Cardano.Timeseries.Domain.Instant +import Cardano.Timeseries.Domain.Timeseries (TimeseriesVector) +import Cardano.Timeseries.Interp.Types (InterpM) + +import Control.DeepSeq (NFData) +import Data.Text (unpack, Text) +import Data.Word (Word64) +import GHC.Generics (Generic) + +type FunctionValue = Value -> InterpM Value + +-- | A model of values that queries interpret into. +data Value where + -- | A scalar. + Scalar :: Double -> Value + -- | A range vector. + RangeVector :: TimeseriesVector Value -> Value + -- | An instant vector. + InstantVector :: InstantVector Value -> Value + -- | A pair. + Pair :: Value -> Value -> Value + -- | Truth. + Truth :: Value + -- | Falsity. + Falsity :: Value + -- | Duration (milliseconds) + Duration :: Word64 -> Value + -- | Timestamp (milliseconds since epoch) + Timestamp :: Word64 -> Value + -- | Function + Function :: FunctionValue -> Value + -- | Text + Text :: Text -> Value deriving Generic + +instance NFData Value + +instance Show Value where + show (Scalar x) = show x + show (RangeVector x) = unpack (asText x) + show (InstantVector x) = unpack (asText x) + show (Pair x y) = "(" <> show x <> ", " <> show y <> ")" + show Truth = "true" + show Falsity = "false" + show (Duration d) = show d <> "ms" + show (Timestamp t) = show t + show (Function _) = "" + show (Text t) = show t + +fromBool :: Bool -> Value +fromBool Prelude.True = Truth +fromBool Prelude.False = Falsity diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store.hs new file mode 100644 index 00000000000..fe1febc7cab --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store.hs @@ -0,0 +1,41 @@ +{-# LANGUAGE FunctionalDependencies #-} + +module Cardano.Timeseries.Store(Store(..), stalenessConstant) where + +import Cardano.Timeseries.Domain.Instant +import Cardano.Timeseries.Domain.Types + +import Data.Set (Set) +import Data.Word (Word64) + +-- | Milliseconds +stalenessConstant :: Word64 +stalenessConstant = 5 * 60 * 1000 + +-- | A type-class witnessing that `s` is a metric-store of `a`. +class Store s a | s -> a where + -- | Insert an instant into the store under a metric name. + insert :: s -> MetricIdentifier -> Instant a -> s + + -- | Delete all entries older than the specified `Timestamp` from the store + truncate :: s -> Timestamp -> s + + -- | Compute a point vector of type `a` such that the timestamp of every point in the vector + -- | lies within the staleness window of the target timestamp and is the most recent of all + -- | points in the store sharing a series. + evaluate :: s -> MetricIdentifier -> Timestamp -> InstantVector a + + -- | Find the earliest occurrence of the metric in the store, if any. + earliest :: s -> MetricIdentifier -> Maybe Timestamp + + -- | Find the latest occurrence of the metric in the store, if any. + latest :: s -> MetricIdentifier -> Maybe Timestamp + + -- | An empty store. + new :: s + + -- A set of metric identifies in the store. + metrics :: s -> Set MetricIdentifier + + -- | Total number of (, , , ) tuples. + count :: s -> Int diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Flat.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Flat.hs new file mode 100644 index 00000000000..7cc9abd7ce1 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Flat.hs @@ -0,0 +1,74 @@ +{-# LANGUAGE DeriveFunctor #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE RecordWildCards #-} +module Cardano.Timeseries.Store.Flat(Flat, Point(..)) where + +import Cardano.Timeseries.Domain.Instant (Instant (..), InstantVector, share) +import qualified Cardano.Timeseries.Domain.Instant as Instant +import Cardano.Timeseries.Domain.Types +import Cardano.Timeseries.Store +import Cardano.Timeseries.Util (toMaybe) + +import Prelude hiding (Foldable (..)) + +import Control.DeepSeq (NFData) +import Data.Foldable (Foldable (..)) +import Data.Set (fromList) +import GHC.Generics (Generic) + +data Point a = Point { + name :: MetricIdentifier, + instant :: Instant a +} deriving (Show, Eq, Functor, Generic) + +instance NFData a => NFData (Point a) + +type Flat a = [Point a] + +instance Store (Flat a) a where + insert :: Flat a -> MetricIdentifier -> Instant a -> Flat a + insert store metric instant = Point metric instant : store + + truncate store cutoff = filter f store where + f Point{instant} = instant.timestamp >= cutoff + + evaluate :: Flat a -> MetricIdentifier -> Timestamp -> InstantVector a + evaluate store targetMetric targetTime = updateTime $ foldl' choose [] store where + + updateTime :: InstantVector a -> InstantVector a + updateTime = fmap (\i -> Instant i.labels targetTime i.value) + + choose :: InstantVector a -> Point a -> InstantVector a + choose acc point = accumulate acc (toMaybe (satisfies point) point) where + + -- | Does that point match target metric name? + -- | Does that point lie within the staleness window? + satisfies :: Point a -> Bool + satisfies x = x.name == targetMetric + && x.instant.timestamp + stalenessConstant >= targetTime + && x.instant.timestamp <= targetTime + + accumulate :: InstantVector a -> Maybe (Point a) -> InstantVector a + accumulate acc' Nothing = acc' + accumulate acc' (Just p_) = accumulateInt acc' p_ where + accumulateInt :: InstantVector a -> Point a -> InstantVector a + accumulateInt [] p = [p.instant] + accumulateInt (x : xs) p | share x p.instant = Instant.mostRecent x p.instant : xs + accumulateInt (x : xs) p = x : accumulateInt xs p + + new = [] + + metrics store = fromList (map (.name) store) + + count = length + + earliest [] _ = Nothing + earliest store ident = Just $ minimum [timestamp instant | Point{..} <- store, name == ident] + + latest [] _ = Nothing + latest store ident = Just $ maximum [timestamp instant | Point{..} <- store, name == ident] diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Flat/Parser.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Flat/Parser.hs new file mode 100644 index 00000000000..24239bb9fba --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Flat/Parser.hs @@ -0,0 +1,62 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Cardano.Timeseries.Store.Flat.Parser(double, point) where + +import Cardano.Timeseries.Domain.Instant +import Cardano.Timeseries.Domain.Types (Labelled, MetricIdentifier, Timestamp) +import Cardano.Timeseries.Store.Flat (Point (..)) + +import Data.Char (isControl) +import Data.Scientific (toRealFloat) +import Data.Set (fromList) +import Data.Text (Text) +import qualified Data.Text as Text +import Data.Void (Void) +import Data.Word (Word64) +import Text.Megaparsec +import Text.Megaparsec.Char (char, space, space1, string) +import Text.Megaparsec.Char.Lexer (decimal, scientific, signed) + +type Parser = Parsec Void Text + +double :: Parser Double +double = toRealFloat <$> signed (pure ()) scientific + +-- | s ::= +-- s [s = s, ..., s = s] +point :: Show a => Parser a -> Parser (Point a) +point value = makePoint + <$> text + <* space + <*> inBrackets labels + <* space + <*> timestamp + <* space1 + <*> value + + where + + makePoint :: MetricIdentifier -> [Labelled Text] -> Timestamp -> a -> Point a + makePoint n ls t v = Point n (Instant (fromList ls) t v) + + comma :: Parser () + comma = space <* string "," <* space + + equals :: Parser () + equals = space <* string "=" <* space + + inBrackets :: Parser a -> Parser a + inBrackets f = string "[" *> space *> f <* space <* string "]" + + text :: Parser Text + text = Text.pack <$> (char '\"' *> many one) <* char '\"' where + one :: Parser Char + one = satisfy (\x -> not (isControl x) && (x /= '"') && (x /= '\n') && (x /= '\r')) + + labels :: Parser [(Text, Text)] + labels = sepBy + ((,) <$> (space *> text) <* equals <*> text) + comma + + timestamp :: Parser Word64 + timestamp = decimal diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Tree.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Tree.hs new file mode 100644 index 00000000000..17a3e96c264 --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Store/Tree.hs @@ -0,0 +1,90 @@ +{-# LANGUAGE DeriveFoldable #-} +{-# LANGUAGE DeriveFunctor #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedRecordDot #-} +module Cardano.Timeseries.Store.Tree(Point(..), Tree, fromFlat) where + +import Cardano.Timeseries.Domain.Instant (Instant (..), InstantVector) +import Cardano.Timeseries.Domain.Types (MetricIdentifier, SeriesIdentifier, Timestamp) +import Cardano.Timeseries.Store +import Cardano.Timeseries.Store.Flat (Flat) +import qualified Cardano.Timeseries.Store.Flat as Flat +import Cardano.Timeseries.Util (range) + +import Prelude hiding (lookup) + +import Control.DeepSeq (NFData) +import Data.Functor +import qualified Data.List as List +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Maybe (fromMaybe) +import Data.Set (Set) +import GHC.Generics (Generic) + +data Point a = Point { + labels :: SeriesIdentifier, + value :: a +} deriving (Show, Ord, Eq, Foldable, Functor, Generic) + +instance NFData a => NFData (Point a) + +type Tree a = Map MetricIdentifier (Map Timestamp [Point a]) + +instance Store (Tree a) a where + insert :: Tree a -> MetricIdentifier -> Instant a -> Tree a + insert store x (Instant ls t v) = flip (Map.insert x) store $ uncurry (Map.insert t) $ + case Map.lookup x store of + Nothing -> ([Point ls v], Map.empty) + Just inner -> (Point ls v : fromMaybe [] (Map.lookup t inner), inner) + + truncate store cutoff = fmap (Map.dropWhileAntitone (< cutoff)) store + + evaluate :: Tree a -> MetricIdentifier -> Timestamp -> InstantVector a + evaluate store x t = case Map.lookup x store of + Just inner -> + updateTime $ convert $ Map.foldlWithKey accumulate Map.empty $ + range + rangeStartExc + rangeEndExc + inner + + where + -- | (-) wraps around, so make sure we do not in case `t` is too small + rangeStartExc = max 0 (t - stalenessConstant) + + rangeEndExc = t + 1 + + updateTime :: InstantVector a -> InstantVector a + updateTime = fmap (\i -> Instant i.labels t i.value) + + accumulate :: Map SeriesIdentifier (Timestamp, a) -> Timestamp -> [Point a] -> Map SeriesIdentifier (Timestamp, a) + accumulate closest tAcc = List.foldl' accumulateInt closest where + accumulateInt closest' (Point ls v) = flip (Map.insert ls) closest' $ + case Map.lookup ls closest' of + Just (t', v') | t' > tAcc -> (t', v') + _ -> (tAcc, v) + + convert :: Map SeriesIdentifier (Timestamp, a) -> InstantVector a + convert = map (\(ls, (tConv, v)) -> Instant ls tConv v) . Map.toList + Nothing -> [] + + new :: Tree a + new = Map.empty + + metrics :: Tree a -> Set MetricIdentifier + metrics = Map.keysSet + + count = sum . (sum . Map.map length <$>) + + earliest store key = Map.lookup key store >>= Map.lookupMin <&> fst + + latest store key = Map.lookup key store >>= Map.lookupMax <&> fst + +fromFlat :: Flat a -> Tree a +fromFlat [] = new +fromFlat (Flat.Point x instant : ps) = insert (fromFlat ps) x instant diff --git a/bench/cardano-timeseries-io/src/Cardano/Timeseries/Util.hs b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Util.hs new file mode 100644 index 00000000000..4a047ebfd8b --- /dev/null +++ b/bench/cardano-timeseries-io/src/Cardano/Timeseries/Util.hs @@ -0,0 +1,31 @@ +module Cardano.Timeseries.Util(toMaybe, maybeToEither, range, getTimeMs, diag) where + +import Prelude hiding (head) + +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Time.Clock.POSIX (getPOSIXTime) +import Data.Word (Word64) + + +toMaybe :: Bool -> a -> Maybe a +toMaybe False _ = Nothing +toMaybe True x = Just x + +maybeToEither :: e -> Maybe a -> Either e a +maybeToEither _ (Just x) = Right x +maybeToEither err Nothing = Left err + +-- | Return submap containing only keys in (lo, hi). +-- | Complexity: O(log(n)). +range :: Ord k => k -> k -> Map k v -> Map k v +range lo hi m = + let (_, m1) = Map.split lo m -- drop all =< lo + (m2, _) = Map.split hi m1 -- drop all >=) hi + in m2 + +getTimeMs :: IO Word64 +getTimeMs = (round . (* 1000)) `fmap` getPOSIXTime + +diag :: a -> (a, a) +diag x = (x, x) diff --git a/cabal.project b/cabal.project index d373a5e20ba..fe404e60aa3 100644 --- a/cabal.project +++ b/cabal.project @@ -33,6 +33,7 @@ packages: bench/plutus-scripts-bench bench/tx-generator bench/cardano-recon-framework + bench/cardano-timeseries-io trace-dispatcher trace-resources trace-forward

R5l`Z~CAck#wAvmcitgwU^hO?SOD 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