hedis-0.16.3: src/Database/Redis/ManualCommands/Tdigest.hs
{-# 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
{ tdigestCreateCompression :: Maybe Integer
-- ^ Compression parameter controlling accuracy and size.
} deriving (Show, Eq)
defaultTDigestCreateOpts :: TDigestCreateOpts
defaultTDigestCreateOpts = TDigestCreateOpts
{ tdigestCreateCompression = Nothing
}
data TDigestMergeOpts = TDigestMergeOpts
{ tdigestMergeCompression :: Maybe Integer
-- ^ Compression parameter for the destination digest.
, tdigestMergeOverride :: Bool
-- ^ Overwrite the destination key if it already exists.
} deriving (Show, Eq)
defaultTDigestMergeOpts :: TDigestMergeOpts
defaultTDigestMergeOpts = TDigestMergeOpts
{ tdigestMergeCompression = Nothing
, tdigestMergeOverride = False
}
data TDigestInfo = TDigestInfo
{ tdigestInfoCompression :: Integer
-- ^ Compression parameter of the digest.
, tdigestInfoCapacity :: Integer
-- ^ Allocated centroid capacity.
, tdigestInfoMergedNodes :: Integer
-- ^ Number of merged centroids.
, tdigestInfoUnmergedNodes :: Integer
-- ^ Number of pending unmerged centroids.
, tdigestInfoMergedWeight :: Integer
-- ^ Weight held by merged centroids.
, tdigestInfoUnmergedWeight :: Integer
-- ^ Weight held by pending unmerged centroids.
, tdigestInfoObservations :: Integer
-- ^ Total number of added observations.
, tdigestInfoTotalCompressions :: Integer
-- ^ Number of performed compression passes.
, tdigestInfoMemoryUsage :: Integer
-- ^ Memory usage in bytes.
} deriving (Show, Eq)
instance RedisResult TDigestInfo where
decode r = do
fields <- decode 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 keys fields =
maybe (Left r) Right . listToMaybe $
[value | key <- keys, value <- maybeToList (lookup key fields)]
maybeToList = maybe [] pure
tdigestCreateOptsToArgs :: TDigestCreateOpts -> [ByteString]
tdigestCreateOptsToArgs TDigestCreateOpts{..} =
maybe [] (\compression -> ["COMPRESSION", encode compression]) tdigestCreateCompression
tdigestMergeOptsToArgs :: TDigestMergeOpts -> [ByteString]
tdigestMergeOptsToArgs TDigestMergeOpts{..} =
compressionArg ++ overrideArg
where
compressionArg = maybe [] (\compression -> ["COMPRESSION", encode compression]) tdigestMergeCompression
overrideArg = ["OVERRIDE" | 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 key values = sendRequest $ ["TDIGEST.ADD", key] ++ map encode (NE.toList 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 key ranks = sendRequest $ ["TDIGEST.BYRANK", key] ++ map encode (NE.toList 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 key ranks = sendRequest $ ["TDIGEST.BYREVRANK", key] ++ map encode (NE.toList 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 key values = sendRequest $ ["TDIGEST.CDF", key] ++ map encode (NE.toList 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 key = tdigestCreateOpts key 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 key opts =
sendRequest $ ["TDIGEST.CREATE", key] ++ tdigestCreateOptsToArgs 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 key = sendRequest ["TDIGEST.INFO", 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 key = sendRequest ["TDIGEST.MAX", 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 destination sources =
tdigestMergeOpts destination sources 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 destination sources opts =
sendRequest $
["TDIGEST.MERGE", destination, encode (fromIntegral (NE.length sources) :: Integer)]
++ NE.toList sources
++ tdigestMergeOptsToArgs 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 key = sendRequest ["TDIGEST.MIN", 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 key quantiles =
sendRequest $ ["TDIGEST.QUANTILE", key] ++ map encode (NE.toList 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 key values = sendRequest $ ["TDIGEST.RANK", key] ++ map encode (NE.toList 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 key = sendRequest ["TDIGEST.RESET", 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 key values = sendRequest $ ["TDIGEST.REVRANK", key] ++ map encode (NE.toList 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 key lowCut highCut =
sendRequest ["TDIGEST.TRIMMED_MEAN", key, encode lowCut, encode highCut]