{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

module Database.Redis.ManualCommands.Tdigest where

import Data.ByteString (ByteString)
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NE
import Data.Maybe (listToMaybe)

import Database.Redis.Core
import Database.Redis.Protocol
import Database.Redis.Types

data TDigestCreateOpts = TDigestCreateOpts
    { TDigestCreateOpts -> Maybe Integer
tdigestCreateCompression :: Maybe Integer
      -- ^ Compression parameter controlling accuracy and size.
    } deriving (Int -> TDigestCreateOpts -> ShowS
[TDigestCreateOpts] -> ShowS
TDigestCreateOpts -> String
(Int -> TDigestCreateOpts -> ShowS)
-> (TDigestCreateOpts -> String)
-> ([TDigestCreateOpts] -> ShowS)
-> Show TDigestCreateOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TDigestCreateOpts -> ShowS
showsPrec :: Int -> TDigestCreateOpts -> ShowS
$cshow :: TDigestCreateOpts -> String
show :: TDigestCreateOpts -> String
$cshowList :: [TDigestCreateOpts] -> ShowS
showList :: [TDigestCreateOpts] -> ShowS
Show, TDigestCreateOpts -> TDigestCreateOpts -> Bool
(TDigestCreateOpts -> TDigestCreateOpts -> Bool)
-> (TDigestCreateOpts -> TDigestCreateOpts -> Bool)
-> Eq TDigestCreateOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TDigestCreateOpts -> TDigestCreateOpts -> Bool
== :: TDigestCreateOpts -> TDigestCreateOpts -> Bool
$c/= :: TDigestCreateOpts -> TDigestCreateOpts -> Bool
/= :: TDigestCreateOpts -> TDigestCreateOpts -> Bool
Eq)

defaultTDigestCreateOpts :: TDigestCreateOpts
defaultTDigestCreateOpts :: TDigestCreateOpts
defaultTDigestCreateOpts = TDigestCreateOpts
    { tdigestCreateCompression :: Maybe Integer
tdigestCreateCompression = Maybe Integer
forall a. Maybe a
Nothing
    }

data TDigestMergeOpts = TDigestMergeOpts
    { TDigestMergeOpts -> Maybe Integer
tdigestMergeCompression :: Maybe Integer
      -- ^ Compression parameter for the destination digest.
    , TDigestMergeOpts -> Bool
tdigestMergeOverride :: Bool
      -- ^ Overwrite the destination key if it already exists.
    } deriving (Int -> TDigestMergeOpts -> ShowS
[TDigestMergeOpts] -> ShowS
TDigestMergeOpts -> String
(Int -> TDigestMergeOpts -> ShowS)
-> (TDigestMergeOpts -> String)
-> ([TDigestMergeOpts] -> ShowS)
-> Show TDigestMergeOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TDigestMergeOpts -> ShowS
showsPrec :: Int -> TDigestMergeOpts -> ShowS
$cshow :: TDigestMergeOpts -> String
show :: TDigestMergeOpts -> String
$cshowList :: [TDigestMergeOpts] -> ShowS
showList :: [TDigestMergeOpts] -> ShowS
Show, TDigestMergeOpts -> TDigestMergeOpts -> Bool
(TDigestMergeOpts -> TDigestMergeOpts -> Bool)
-> (TDigestMergeOpts -> TDigestMergeOpts -> Bool)
-> Eq TDigestMergeOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TDigestMergeOpts -> TDigestMergeOpts -> Bool
== :: TDigestMergeOpts -> TDigestMergeOpts -> Bool
$c/= :: TDigestMergeOpts -> TDigestMergeOpts -> Bool
/= :: TDigestMergeOpts -> TDigestMergeOpts -> Bool
Eq)

defaultTDigestMergeOpts :: TDigestMergeOpts
defaultTDigestMergeOpts :: TDigestMergeOpts
defaultTDigestMergeOpts = TDigestMergeOpts
    { tdigestMergeCompression :: Maybe Integer
tdigestMergeCompression = Maybe Integer
forall a. Maybe a
Nothing
    , tdigestMergeOverride :: Bool
tdigestMergeOverride = Bool
False
    }

data TDigestInfo = TDigestInfo
    { TDigestInfo -> Integer
tdigestInfoCompression :: Integer
      -- ^ Compression parameter of the digest.
    , TDigestInfo -> Integer
tdigestInfoCapacity :: Integer
      -- ^ Allocated centroid capacity.
    , TDigestInfo -> Integer
tdigestInfoMergedNodes :: Integer
      -- ^ Number of merged centroids.
    , TDigestInfo -> Integer
tdigestInfoUnmergedNodes :: Integer
      -- ^ Number of pending unmerged centroids.
    , TDigestInfo -> Integer
tdigestInfoMergedWeight :: Integer
      -- ^ Weight held by merged centroids.
    , TDigestInfo -> Integer
tdigestInfoUnmergedWeight :: Integer
      -- ^ Weight held by pending unmerged centroids.
    , TDigestInfo -> Integer
tdigestInfoObservations :: Integer
      -- ^ Total number of added observations.
    , TDigestInfo -> Integer
tdigestInfoTotalCompressions :: Integer
      -- ^ Number of performed compression passes.
    , TDigestInfo -> Integer
tdigestInfoMemoryUsage :: Integer
      -- ^ Memory usage in bytes.
    } deriving (Int -> TDigestInfo -> ShowS
[TDigestInfo] -> ShowS
TDigestInfo -> String
(Int -> TDigestInfo -> ShowS)
-> (TDigestInfo -> String)
-> ([TDigestInfo] -> ShowS)
-> Show TDigestInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TDigestInfo -> ShowS
showsPrec :: Int -> TDigestInfo -> ShowS
$cshow :: TDigestInfo -> String
show :: TDigestInfo -> String
$cshowList :: [TDigestInfo] -> ShowS
showList :: [TDigestInfo] -> ShowS
Show, TDigestInfo -> TDigestInfo -> Bool
(TDigestInfo -> TDigestInfo -> Bool)
-> (TDigestInfo -> TDigestInfo -> Bool) -> Eq TDigestInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TDigestInfo -> TDigestInfo -> Bool
== :: TDigestInfo -> TDigestInfo -> Bool
$c/= :: TDigestInfo -> TDigestInfo -> Bool
/= :: TDigestInfo -> TDigestInfo -> Bool
Eq)

instance RedisResult TDigestInfo where
    decode :: Reply -> Either Reply TDigestInfo
decode Reply
r = do
        fields <- Reply -> Either Reply [(ByteString, Integer)]
forall a. RedisResult a => Reply -> Either Reply a
decode Reply
r :: Either Reply [(ByteString, Integer)]
        tdigestInfoCompression <- decodeField ["Compression", "compression"] fields
        tdigestInfoCapacity <- decodeField ["Capacity", "capacity"] fields
        tdigestInfoMergedNodes <- decodeField ["Merged nodes", "merged nodes"] fields
        tdigestInfoUnmergedNodes <- decodeField ["Unmerged nodes", "unmerged nodes"] fields
        tdigestInfoMergedWeight <- decodeField ["Merged weight", "merged weight"] fields
        tdigestInfoUnmergedWeight <- decodeField ["Unmerged weight", "unmerged weight"] fields
        tdigestInfoObservations <- decodeField ["Observations", "observations"] fields
        tdigestInfoTotalCompressions <- decodeField ["Total compressions", "total compressions"] fields
        tdigestInfoMemoryUsage <- decodeField ["Memory usage", "memory usage"] fields
        pure TDigestInfo{..}
      where
        decodeField :: [a] -> [(a, b)] -> Either Reply b
decodeField [a]
keys [(a, b)]
fields =
            Either Reply b
-> (b -> Either Reply b) -> Maybe b -> Either Reply b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Reply -> Either Reply b
forall a b. a -> Either a b
Left Reply
r) b -> Either Reply b
forall a b. b -> Either a b
Right (Maybe b -> Either Reply b)
-> ([b] -> Maybe b) -> [b] -> Either Reply b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [b] -> Maybe b
forall a. [a] -> Maybe a
listToMaybe ([b] -> Either Reply b) -> [b] -> Either Reply b
forall a b. (a -> b) -> a -> b
$
                [b
value | a
key <- [a]
keys, b
value <- Maybe b -> [b]
forall {a}. Maybe a -> [a]
maybeToList (a -> [(a, b)] -> Maybe b
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup a
key [(a, b)]
fields)]

        maybeToList :: Maybe a -> [a]
maybeToList = [a] -> (a -> [a]) -> Maybe a -> [a]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] a -> [a]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure

tdigestCreateOptsToArgs :: TDigestCreateOpts -> [ByteString]
tdigestCreateOptsToArgs :: TDigestCreateOpts -> [ByteString]
tdigestCreateOptsToArgs TDigestCreateOpts{Maybe Integer
tdigestCreateCompression :: TDigestCreateOpts -> Maybe Integer
tdigestCreateCompression :: Maybe Integer
..} =
    [ByteString]
-> (Integer -> [ByteString]) -> Maybe Integer -> [ByteString]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Integer
compression -> [ByteString
"COMPRESSION", Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode Integer
compression]) Maybe Integer
tdigestCreateCompression

tdigestMergeOptsToArgs :: TDigestMergeOpts -> [ByteString]
tdigestMergeOptsToArgs :: TDigestMergeOpts -> [ByteString]
tdigestMergeOptsToArgs TDigestMergeOpts{Bool
Maybe Integer
tdigestMergeCompression :: TDigestMergeOpts -> Maybe Integer
tdigestMergeOverride :: TDigestMergeOpts -> Bool
tdigestMergeCompression :: Maybe Integer
tdigestMergeOverride :: Bool
..} =
    [ByteString]
compressionArg [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
overrideArg
  where
    compressionArg :: [ByteString]
compressionArg = [ByteString]
-> (Integer -> [ByteString]) -> Maybe Integer -> [ByteString]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Integer
compression -> [ByteString
"COMPRESSION", Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode Integer
compression]) Maybe Integer
tdigestMergeCompression
    overrideArg :: [ByteString]
overrideArg = [ByteString
"OVERRIDE" | Bool
tdigestMergeOverride]

-- |Adds one or more observations to a t-digest sketch (<https://redis.io/commands/tdigest.add>).
--
-- /O(n \log k)/, where /n/ is the number of observations and /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestAdd
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> NonEmpty Double -- ^ Observations to add.
    -> m (f Status)
tdigestAdd :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty Double -> m (f Status)
tdigestAdd ByteString
key NonEmpty Double
values = [ByteString] -> m (f Status)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f Status)) -> [ByteString] -> m (f Status)
forall a b. (a -> b) -> a -> b
$ [ByteString
"TDIGEST.ADD", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ (Double -> ByteString) -> [Double] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Double -> ByteString
forall a. RedisArg a => a -> ByteString
encode (NonEmpty Double -> [Double]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty Double
values)

-- |Returns observations by their ascending ranks from a t-digest sketch (<https://redis.io/commands/tdigest.byrank>).
--
-- /O(n \log k)/, where /n/ is the number of requested ranks and /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestByrank
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> NonEmpty Integer -- ^ Requested ranks.
    -> m (f [Double])
tdigestByrank :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty Integer -> m (f [Double])
tdigestByrank ByteString
key NonEmpty Integer
ranks = [ByteString] -> m (f [Double])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [Double])) -> [ByteString] -> m (f [Double])
forall a b. (a -> b) -> a -> b
$ [ByteString
"TDIGEST.BYRANK", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ (Integer -> ByteString) -> [Integer] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode (NonEmpty Integer -> [Integer]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty Integer
ranks)

-- |Returns observations by their descending ranks from a t-digest sketch (<https://redis.io/commands/tdigest.byrevrank>).
--
-- /O(n \log k)/, where /n/ is the number of requested reverse ranks and /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestByrevrank
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> NonEmpty Integer -- ^ Requested reverse ranks.
    -> m (f [Double])
tdigestByrevrank :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty Integer -> m (f [Double])
tdigestByrevrank ByteString
key NonEmpty Integer
ranks = [ByteString] -> m (f [Double])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [Double])) -> [ByteString] -> m (f [Double])
forall a b. (a -> b) -> a -> b
$ [ByteString
"TDIGEST.BYREVRANK", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ (Integer -> ByteString) -> [Integer] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode (NonEmpty Integer -> [Integer]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty Integer
ranks)

-- |Returns cumulative distribution estimates for one or more observations (<https://redis.io/commands/tdigest.cdf>).
--
-- /O(n \log k)/, where /n/ is the number of queried values and /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestCdf
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> NonEmpty Double -- ^ Observations to query.
    -> m (f [Double])
tdigestCdf :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty Double -> m (f [Double])
tdigestCdf ByteString
key NonEmpty Double
values = [ByteString] -> m (f [Double])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [Double])) -> [ByteString] -> m (f [Double])
forall a b. (a -> b) -> a -> b
$ [ByteString
"TDIGEST.CDF", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ (Double -> ByteString) -> [Double] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Double -> ByteString
forall a. RedisArg a => a -> ByteString
encode (NonEmpty Double -> [Double]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty Double
values)

-- |Creates an empty t-digest sketch (<https://redis.io/commands/tdigest.create>).
--
-- /O(1)/
--
-- Since RedisBloom 2.4.0
tdigestCreate
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch to create.
    -> m (f Status)
tdigestCreate :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f Status)
tdigestCreate ByteString
key = ByteString -> TDigestCreateOpts -> m (f Status)
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> TDigestCreateOpts -> m (f Status)
tdigestCreateOpts ByteString
key TDigestCreateOpts
defaultTDigestCreateOpts

-- |Creates an empty t-digest sketch (<https://redis.io/commands/tdigest.create>).
--
-- /O(1)/
--
-- Since RedisBloom 2.4.0
tdigestCreateOpts
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch to create.
    -> TDigestCreateOpts -- ^ Creation options.
    -> m (f Status)
tdigestCreateOpts :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> TDigestCreateOpts -> m (f Status)
tdigestCreateOpts ByteString
key TDigestCreateOpts
opts =
    [ByteString] -> m (f Status)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f Status)) -> [ByteString] -> m (f Status)
forall a b. (a -> b) -> a -> b
$ [ByteString
"TDIGEST.CREATE", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ TDigestCreateOpts -> [ByteString]
tdigestCreateOptsToArgs TDigestCreateOpts
opts

-- |Returns information about a t-digest sketch (<https://redis.io/commands/tdigest.info>).
--
-- /O(1)/
--
-- Since RedisBloom 2.4.0
tdigestInfo
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> m (f TDigestInfo)
tdigestInfo :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f TDigestInfo)
tdigestInfo ByteString
key = [ByteString] -> m (f TDigestInfo)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"TDIGEST.INFO", ByteString
key]

-- |Returns the maximum observation in a t-digest sketch (<https://redis.io/commands/tdigest.max>).
--
-- /O(1)/
--
-- Since RedisBloom 2.4.0
tdigestMax
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> m (f Double)
tdigestMax :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f Double)
tdigestMax ByteString
key = [ByteString] -> m (f Double)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"TDIGEST.MAX", ByteString
key]

-- |Merges multiple t-digest sketches into a destination sketch (<https://redis.io/commands/tdigest.merge>).
--
-- /O(n \cdot k)/, where /n/ is the number of source sketches and /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestMerge
    :: (RedisCtx m f)
    => ByteString -- ^ Destination key.
    -> NonEmpty ByteString -- ^ Source sketch keys.
    -> m (f Status)
tdigestMerge :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty ByteString -> m (f Status)
tdigestMerge ByteString
destination NonEmpty ByteString
sources =
    ByteString
-> NonEmpty ByteString -> TDigestMergeOpts -> m (f Status)
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString
-> NonEmpty ByteString -> TDigestMergeOpts -> m (f Status)
tdigestMergeOpts ByteString
destination NonEmpty ByteString
sources TDigestMergeOpts
defaultTDigestMergeOpts

-- |Merges multiple t-digest sketches into a destination sketch (<https://redis.io/commands/tdigest.merge>).
--
-- /O(n \cdot k)/, where /n/ is the number of source sketches and /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestMergeOpts
    :: (RedisCtx m f)
    => ByteString -- ^ Destination key.
    -> NonEmpty ByteString -- ^ Source sketch keys.
    -> TDigestMergeOpts -- ^ Merge options.
    -> m (f Status)
tdigestMergeOpts :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString
-> NonEmpty ByteString -> TDigestMergeOpts -> m (f Status)
tdigestMergeOpts ByteString
destination NonEmpty ByteString
sources TDigestMergeOpts
opts =
    [ByteString] -> m (f Status)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f Status)) -> [ByteString] -> m (f Status)
forall a b. (a -> b) -> a -> b
$
        [ByteString
"TDIGEST.MERGE", ByteString
destination, Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (NonEmpty ByteString -> Int
forall a. NonEmpty a -> Int
NE.length NonEmpty ByteString
sources) :: Integer)]
            [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ NonEmpty ByteString -> [ByteString]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty ByteString
sources
            [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ TDigestMergeOpts -> [ByteString]
tdigestMergeOptsToArgs TDigestMergeOpts
opts

-- |Returns the minimum observation in a t-digest sketch (<https://redis.io/commands/tdigest.min>).
--
-- /O(1)/
--
-- Since RedisBloom 2.4.0
tdigestMin
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> m (f Double)
tdigestMin :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f Double)
tdigestMin ByteString
key = [ByteString] -> m (f Double)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"TDIGEST.MIN", ByteString
key]

-- |Returns quantile estimates for one or more quantiles (<https://redis.io/commands/tdigest.quantile>).
--
-- /O(n \log k)/, where /n/ is the number of quantiles and /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestQuantile
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> NonEmpty Double -- ^ Quantiles to estimate.
    -> m (f [Double])
tdigestQuantile :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty Double -> m (f [Double])
tdigestQuantile ByteString
key NonEmpty Double
quantiles =
    [ByteString] -> m (f [Double])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [Double])) -> [ByteString] -> m (f [Double])
forall a b. (a -> b) -> a -> b
$ [ByteString
"TDIGEST.QUANTILE", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ (Double -> ByteString) -> [Double] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Double -> ByteString
forall a. RedisArg a => a -> ByteString
encode (NonEmpty Double -> [Double]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty Double
quantiles)

-- |Returns ascending rank estimates for one or more observations (<https://redis.io/commands/tdigest.rank>).
--
-- /O(n \log k)/, where /n/ is the number of observations and /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestRank
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> NonEmpty Double -- ^ Observations to rank.
    -> m (f [Integer])
tdigestRank :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty Double -> m (f [Integer])
tdigestRank ByteString
key NonEmpty Double
values = [ByteString] -> m (f [Integer])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [Integer]))
-> [ByteString] -> m (f [Integer])
forall a b. (a -> b) -> a -> b
$ [ByteString
"TDIGEST.RANK", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ (Double -> ByteString) -> [Double] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Double -> ByteString
forall a. RedisArg a => a -> ByteString
encode (NonEmpty Double -> [Double]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty Double
values)

-- |Resets a t-digest sketch to its empty state (<https://redis.io/commands/tdigest.reset>).
--
-- /O(1)/
--
-- Since RedisBloom 2.4.0
tdigestReset
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> m (f Status)
tdigestReset :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f Status)
tdigestReset ByteString
key = [ByteString] -> m (f Status)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"TDIGEST.RESET", ByteString
key]

-- |Returns descending rank estimates for one or more observations (<https://redis.io/commands/tdigest.revrank>).
--
-- /O(n \log k)/, where /n/ is the number of observations and /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestRevrank
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> NonEmpty Double -- ^ Observations to rank.
    -> m (f [Integer])
tdigestRevrank :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty Double -> m (f [Integer])
tdigestRevrank ByteString
key NonEmpty Double
values = [ByteString] -> m (f [Integer])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [Integer]))
-> [ByteString] -> m (f [Integer])
forall a b. (a -> b) -> a -> b
$ [ByteString
"TDIGEST.REVRANK", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ (Double -> ByteString) -> [Double] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Double -> ByteString
forall a. RedisArg a => a -> ByteString
encode (NonEmpty Double -> [Double]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty Double
values)

-- |Returns the trimmed mean for observations within the provided quantile range (<https://redis.io/commands/tdigest.trimmed_mean>).
--
-- /O(\log k)/, where /k/ is the compression parameter.
--
-- Since RedisBloom 2.4.0
tdigestTrimmedMean
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the t-digest sketch.
    -> Double -- ^ Lower quantile bound.
    -> Double -- ^ Upper quantile bound.
    -> m (f Double)
tdigestTrimmedMean :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> Double -> Double -> m (f Double)
tdigestTrimmedMean ByteString
key Double
lowCut Double
highCut =
    [ByteString] -> m (f Double)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"TDIGEST.TRIMMED_MEAN", ByteString
key, Double -> ByteString
forall a. RedisArg a => a -> ByteString
encode Double
lowCut, Double -> ByteString
forall a. RedisArg a => a -> ByteString
encode Double
highCut]