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

module Database.Redis.ManualCommands.BF where

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

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

data BFInfo = BFInfo
    { BFInfo -> Integer
bfInfoCapacity :: Integer
      -- ^ Number of unique items that can be stored before scaling is required.
    , BFInfo -> Integer
bfInfoSize :: Integer
      -- ^ Number of bytes allocated for the Bloom filter.
    , BFInfo -> Integer
bfInfoFilters :: Integer
      -- ^ Number of sub-filters.
    , BFInfo -> Integer
bfInfoItems :: Integer
      -- ^ Number of unique inserted items detected by the filter.
    , BFInfo -> Integer
bfInfoExpansion :: Integer
      -- ^ Expansion rate used when a new sub-filter is created.
    } deriving (Int -> BFInfo -> ShowS
[BFInfo] -> ShowS
BFInfo -> String
(Int -> BFInfo -> ShowS)
-> (BFInfo -> String) -> ([BFInfo] -> ShowS) -> Show BFInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BFInfo -> ShowS
showsPrec :: Int -> BFInfo -> ShowS
$cshow :: BFInfo -> String
show :: BFInfo -> String
$cshowList :: [BFInfo] -> ShowS
showList :: [BFInfo] -> ShowS
Show, BFInfo -> BFInfo -> Bool
(BFInfo -> BFInfo -> Bool)
-> (BFInfo -> BFInfo -> Bool) -> Eq BFInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BFInfo -> BFInfo -> Bool
== :: BFInfo -> BFInfo -> Bool
$c/= :: BFInfo -> BFInfo -> Bool
/= :: BFInfo -> BFInfo -> Bool
Eq)

instance RedisResult BFInfo where
    decode :: Reply -> Either Reply BFInfo
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)]
        bfInfoCapacity <- decodeField "Capacity" fields
        bfInfoSize <- decodeField "Size" fields
        bfInfoFilters <- decodeField "Number of filters" fields
        bfInfoItems <- decodeField "Number of items inserted" fields
        bfInfoExpansion <- decodeField "Expansion rate" fields
        pure BFInfo{..}
      where
        decodeField :: a -> [(a, b)] -> Either Reply b
decodeField a
key [(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 (a -> [(a, b)] -> Maybe b
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup a
key [(a, b)]
fields)

data BFReserveOpts = BFReserveOpts
    { BFReserveOpts -> Maybe Integer
bfReserveExpansion :: Maybe Integer
      -- ^ Expansion rate for newly created sub-filters once capacity is reached.
    , BFReserveOpts -> Bool
bfReserveNonScaling :: Bool
      -- ^ Prevent creation of additional sub-filters when initial capacity is reached.
    } deriving (Int -> BFReserveOpts -> ShowS
[BFReserveOpts] -> ShowS
BFReserveOpts -> String
(Int -> BFReserveOpts -> ShowS)
-> (BFReserveOpts -> String)
-> ([BFReserveOpts] -> ShowS)
-> Show BFReserveOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BFReserveOpts -> ShowS
showsPrec :: Int -> BFReserveOpts -> ShowS
$cshow :: BFReserveOpts -> String
show :: BFReserveOpts -> String
$cshowList :: [BFReserveOpts] -> ShowS
showList :: [BFReserveOpts] -> ShowS
Show, BFReserveOpts -> BFReserveOpts -> Bool
(BFReserveOpts -> BFReserveOpts -> Bool)
-> (BFReserveOpts -> BFReserveOpts -> Bool) -> Eq BFReserveOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BFReserveOpts -> BFReserveOpts -> Bool
== :: BFReserveOpts -> BFReserveOpts -> Bool
$c/= :: BFReserveOpts -> BFReserveOpts -> Bool
/= :: BFReserveOpts -> BFReserveOpts -> Bool
Eq)

defaultBFReserveOpts :: BFReserveOpts
defaultBFReserveOpts :: BFReserveOpts
defaultBFReserveOpts = BFReserveOpts
    { bfReserveExpansion :: Maybe Integer
bfReserveExpansion = Maybe Integer
forall a. Maybe a
Nothing
    , bfReserveNonScaling :: Bool
bfReserveNonScaling = Bool
False
    }

data BFInsertOpts = BFInsertOpts
    { BFInsertOpts -> Maybe Integer
bfInsertCapacity :: Maybe Integer
      -- ^ Initial capacity to use if a new filter is created.
    , BFInsertOpts -> Maybe Double
bfInsertError :: Maybe Double
      -- ^ Desired false positive probability to use if a new filter is created.
    , BFInsertOpts -> Maybe Integer
bfInsertExpansion :: Maybe Integer
      -- ^ Expansion rate for additional sub-filters.
    , BFInsertOpts -> Bool
bfInsertNoCreate :: Bool
      -- ^ Return an error instead of creating the filter when the key does not exist.
    , BFInsertOpts -> Bool
bfInsertNonScaling :: Bool
      -- ^ Prevent creation of additional sub-filters when capacity is reached.
    } deriving (Int -> BFInsertOpts -> ShowS
[BFInsertOpts] -> ShowS
BFInsertOpts -> String
(Int -> BFInsertOpts -> ShowS)
-> (BFInsertOpts -> String)
-> ([BFInsertOpts] -> ShowS)
-> Show BFInsertOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BFInsertOpts -> ShowS
showsPrec :: Int -> BFInsertOpts -> ShowS
$cshow :: BFInsertOpts -> String
show :: BFInsertOpts -> String
$cshowList :: [BFInsertOpts] -> ShowS
showList :: [BFInsertOpts] -> ShowS
Show, BFInsertOpts -> BFInsertOpts -> Bool
(BFInsertOpts -> BFInsertOpts -> Bool)
-> (BFInsertOpts -> BFInsertOpts -> Bool) -> Eq BFInsertOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BFInsertOpts -> BFInsertOpts -> Bool
== :: BFInsertOpts -> BFInsertOpts -> Bool
$c/= :: BFInsertOpts -> BFInsertOpts -> Bool
/= :: BFInsertOpts -> BFInsertOpts -> Bool
Eq)

defaultBFInsertOpts :: BFInsertOpts
defaultBFInsertOpts :: BFInsertOpts
defaultBFInsertOpts = BFInsertOpts
    { bfInsertCapacity :: Maybe Integer
bfInsertCapacity = Maybe Integer
forall a. Maybe a
Nothing
    , bfInsertError :: Maybe Double
bfInsertError = Maybe Double
forall a. Maybe a
Nothing
    , bfInsertExpansion :: Maybe Integer
bfInsertExpansion = Maybe Integer
forall a. Maybe a
Nothing
    , bfInsertNoCreate :: Bool
bfInsertNoCreate = Bool
False
    , bfInsertNonScaling :: Bool
bfInsertNonScaling = Bool
False
    }

bfReserveOptsToArgs :: BFReserveOpts -> [ByteString]
bfReserveOptsToArgs :: BFReserveOpts -> [ByteString]
bfReserveOptsToArgs BFReserveOpts{Bool
Maybe Integer
bfReserveExpansion :: BFReserveOpts -> Maybe Integer
bfReserveNonScaling :: BFReserveOpts -> Bool
bfReserveExpansion :: Maybe Integer
bfReserveNonScaling :: Bool
..} =
    [ByteString]
expansionArg [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
nonScalingArg
  where
    expansionArg :: [ByteString]
expansionArg = [ByteString]
-> (Integer -> [ByteString]) -> Maybe Integer -> [ByteString]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Integer
expansion -> [ByteString
"EXPANSION", Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode Integer
expansion]) Maybe Integer
bfReserveExpansion
    nonScalingArg :: [ByteString]
nonScalingArg = [ByteString
"NONSCALING" | Bool
bfReserveNonScaling]

bfInsertOptsToArgs :: BFInsertOpts -> [ByteString]
bfInsertOptsToArgs :: BFInsertOpts -> [ByteString]
bfInsertOptsToArgs BFInsertOpts{Bool
Maybe Double
Maybe Integer
bfInsertCapacity :: BFInsertOpts -> Maybe Integer
bfInsertError :: BFInsertOpts -> Maybe Double
bfInsertExpansion :: BFInsertOpts -> Maybe Integer
bfInsertNoCreate :: BFInsertOpts -> Bool
bfInsertNonScaling :: BFInsertOpts -> Bool
bfInsertCapacity :: Maybe Integer
bfInsertError :: Maybe Double
bfInsertExpansion :: Maybe Integer
bfInsertNoCreate :: Bool
bfInsertNonScaling :: Bool
..} =
    [ByteString]
capacityArg [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
errorArg [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
expansionArg [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
noCreateArg [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
nonScalingArg
  where
    capacityArg :: [ByteString]
capacityArg = [ByteString]
-> (Integer -> [ByteString]) -> Maybe Integer -> [ByteString]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Integer
capacity -> [ByteString
"CAPACITY", Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode Integer
capacity]) Maybe Integer
bfInsertCapacity
    errorArg :: [ByteString]
errorArg = [ByteString]
-> (Double -> [ByteString]) -> Maybe Double -> [ByteString]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Double
err -> [ByteString
"ERROR", Double -> ByteString
forall a. RedisArg a => a -> ByteString
encode Double
err]) Maybe Double
bfInsertError
    expansionArg :: [ByteString]
expansionArg = [ByteString]
-> (Integer -> [ByteString]) -> Maybe Integer -> [ByteString]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Integer
expansion -> [ByteString
"EXPANSION", Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode Integer
expansion]) Maybe Integer
bfInsertExpansion
    noCreateArg :: [ByteString]
noCreateArg = [ByteString
"NOCREATE" | Bool
bfInsertNoCreate]
    nonScalingArg :: [ByteString]
nonScalingArg = [ByteString
"NONSCALING" | Bool
bfInsertNonScaling]

-- |Adds an item to a Bloom filter (<https://redis.io/commands/bf.add>).
--
-- A filter is created automatically if the key does not exist.
--
-- /O(k)/, where /k/ is the number of hash functions used by the last sub-filter.
--
-- Since RedisBloom 1.0.0
bfadd
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> ByteString -- ^ Item to add to the Bloom filter.
    -> m (f Bool)
bfadd :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> ByteString -> m (f Bool)
bfadd ByteString
key ByteString
item = [ByteString] -> m (f Bool)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"BF.ADD", ByteString
key, ByteString
item]

-- |Returns the cardinality of a Bloom filter (<https://redis.io/commands/bf.card>).
--
-- Returns @0@ when the key does not exist.
--
-- /O(1)/
--
-- Since RedisBloom 2.4.4
bfcard
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> m (f Integer)
bfcard :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f Integer)
bfcard ByteString
key = [ByteString] -> m (f Integer)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"BF.CARD", ByteString
key]

-- |Determines whether an item was added to a Bloom filter (<https://redis.io/commands/bf.exists>).
--
-- Returns 'False' when the key does not exist or the item was definitely not added.
--
-- /O(k)/, where $k$ is the number of hash functions used by the last sub-filter.
--
-- Since RedisBloom 1.0.0
bfexists
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> ByteString -- ^ Item to check.
    -> m (f Bool)
bfexists :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> ByteString -> m (f Bool)
bfexists ByteString
key ByteString
item = [ByteString] -> m (f Bool)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"BF.EXISTS", ByteString
key, ByteString
item]

-- |Returns information about a Bloom filter (<https://redis.io/commands/bf.info>).
--
-- /O(1)/
--
-- Since RedisBloom 1.0.0
bfinfo
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> m (f BFInfo)
bfinfo :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f BFInfo)
bfinfo ByteString
key = [ByteString] -> m (f BFInfo)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"BF.INFO", ByteString
key]

-- |Returns the configured capacity of a Bloom filter (<https://redis.io/commands/bf.info>).
--
-- /O(1)/
--
-- Since RedisBloom 1.0.0
bfinfoCapacity
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> m (f [Integer])
bfinfoCapacity :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f [Integer])
bfinfoCapacity ByteString
key = [ByteString] -> m (f [Integer])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"BF.INFO", ByteString
key, ByteString
"CAPACITY"]

-- |Returns the size in bytes of a Bloom filter (<https://redis.io/commands/bf.info>).
--
-- /O(1)/
--
-- Since RedisBloom 1.0.0
bfinfoSize
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> m (f [Integer])
bfinfoSize :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f [Integer])
bfinfoSize ByteString
key = [ByteString] -> m (f [Integer])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"BF.INFO", ByteString
key, ByteString
"SIZE"]

-- |Returns the number of sub-filters in a Bloom filter (<https://redis.io/commands/bf.info>).
--
-- /O(1)/
--
-- Since RedisBloom 1.0.0
bfinfoFilters
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> m (f [Integer])
bfinfoFilters :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f [Integer])
bfinfoFilters ByteString
key = [ByteString] -> m (f [Integer])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"BF.INFO", ByteString
key, ByteString
"FILTERS"]

-- |Returns the number of unique inserted items detected by a Bloom filter (<https://redis.io/commands/bf.info>).
--
-- /O(1)/
--
-- Since RedisBloom 1.0.0
bfinfoItems
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> m (f [Integer])
bfinfoItems :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f [Integer])
bfinfoItems ByteString
key = [ByteString] -> m (f [Integer])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"BF.INFO", ByteString
key, ByteString
"ITEMS"]

-- |Returns the expansion rate of a Bloom filter (<https://redis.io/commands/bf.info>).
--
-- /O(1)/
--
-- Returns Nothing for the non scaling filters.
--
-- Since RedisBloom 1.0.0
bfinfoExpansion
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> m (f [Maybe Integer])
bfinfoExpansion :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f [Maybe Integer])
bfinfoExpansion ByteString
key = [ByteString] -> m (f [Maybe Integer])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"BF.INFO", ByteString
key, ByteString
"EXPANSION"]

-- |Adds one or more items to a Bloom filter, creating it when needed (<https://redis.io/commands/bf.insert>).
--
-- This is equivalent to inserting with default options and automatic creation enabled.
--
-- /O(kn)/, where /k/ is the number of hash functions and /n/ is the number of items.
--
-- Since RedisBloom 1.0.0
bfinsert
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> NonEmpty ByteString -- ^ Items to add.
    -> m (f [Bool])
bfinsert :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty ByteString -> m (f [Bool])
bfinsert ByteString
key NonEmpty ByteString
items = ByteString -> NonEmpty ByteString -> BFInsertOpts -> m (f [Bool])
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty ByteString -> BFInsertOpts -> m (f [Bool])
bfinsertOpts ByteString
key NonEmpty ByteString
items BFInsertOpts
defaultBFInsertOpts

-- |Adds one or more items to a Bloom filter, creating it when needed (<https://redis.io/commands/bf.insert>).
--
-- /O(kn)/, where /k/ is the number of hash functions and /n/ is the number of items.
--
-- Since RedisBloom 1.0.0
bfinsertOpts
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> NonEmpty ByteString -- ^ Items to add.
    -> BFInsertOpts -- ^ Optional creation and scaling parameters.
    -> m (f [Bool])
bfinsertOpts :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty ByteString -> BFInsertOpts -> m (f [Bool])
bfinsertOpts ByteString
key NonEmpty ByteString
items BFInsertOpts
opts =
    [ByteString] -> m (f [Bool])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [Bool])) -> [ByteString] -> m (f [Bool])
forall a b. (a -> b) -> a -> b
$ [ByteString
"BF.INSERT", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ BFInsertOpts -> [ByteString]
bfInsertOptsToArgs BFInsertOpts
opts [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString
"ITEMS"] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ NonEmpty ByteString -> [ByteString]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty ByteString
items

-- |Adds one or more items to a Bloom filter (<https://redis.io/commands/bf.madd>).
--
-- A filter is created automatically if the key does not exist.
--
-- /O(kn)/, where /k/ is the number of hash functions and /n/ is the number of items.
--
-- Since RedisBloom 1.0.0
bfmadd
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> NonEmpty ByteString -- ^ Items to add.
    -> m (f [Bool])
bfmadd :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty ByteString -> m (f [Bool])
bfmadd ByteString
key NonEmpty ByteString
items = [ByteString] -> m (f [Bool])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [Bool])) -> [ByteString] -> m (f [Bool])
forall a b. (a -> b) -> a -> b
$ [ByteString
"BF.MADD", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ NonEmpty ByteString -> [ByteString]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty ByteString
items

-- |Checks whether one or more items were added to a Bloom filter (<https://redis.io/commands/bf.mexists>).
--
-- A 'False' result means the item is definitely absent, or the key does not exist.
--
-- /O(kn)/, where /k/ is the number of hash functions and /n/ is the number of items.
--
-- Since RedisBloom 1.0.0
bfmexists
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter.
    -> NonEmpty ByteString -- ^ Items to check.
    -> m (f [Bool])
bfmexists :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty ByteString -> m (f [Bool])
bfmexists ByteString
key NonEmpty ByteString
items = [ByteString] -> m (f [Bool])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [Bool])) -> [ByteString] -> m (f [Bool])
forall a b. (a -> b) -> a -> b
$ [ByteString
"BF.MEXISTS", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ NonEmpty ByteString -> [ByteString]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty ByteString
items

-- |Creates an empty Bloom filter (<https://redis.io/commands/bf.reserve>).
--
-- The filter will fail if the key already exists.
--
-- /O(1)/
--
-- Since RedisBloom 1.0.0
bfreserve
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter to create.
    -> Double -- ^ Desired false positive probability, between @0@ and @1@.
    -> Integer -- ^ Initial capacity.
    -> m (f Status)
bfreserve :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> Double -> Integer -> m (f Status)
bfreserve ByteString
key Double
errorRate Integer
capacity = ByteString -> Double -> Integer -> BFReserveOpts -> m (f Status)
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> Double -> Integer -> BFReserveOpts -> m (f Status)
bfreserveOpts ByteString
key Double
errorRate Integer
capacity BFReserveOpts
defaultBFReserveOpts

-- |Creates an empty Bloom filter (<https://redis.io/commands/bf.reserve>).
--
-- /O(1)/
--
-- Since RedisBloom 1.0.0
bfreserveOpts
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Bloom filter to create.
    -> Double -- ^ Desired false positive probability, between @0@ and @1@.
    -> Integer -- ^ Initial capacity.
    -> BFReserveOpts -- ^ Scaling options for the reserved filter.
    -> m (f Status)
bfreserveOpts :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> Double -> Integer -> BFReserveOpts -> m (f Status)
bfreserveOpts ByteString
key Double
errorRate Integer
capacity BFReserveOpts
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
"BF.RESERVE", ByteString
key, Double -> ByteString
forall a. RedisArg a => a -> ByteString
encode Double
errorRate, Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode Integer
capacity] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ BFReserveOpts -> [ByteString]
bfReserveOptsToArgs BFReserveOpts
opts