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

module Database.Redis.ManualCommands.CF where

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

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

data CFInfo = CFInfo
    { CFInfo -> Integer
cfInfoSize :: Integer
      -- ^ Number of bytes allocated for the Cuckoo filter.
    , CFInfo -> Integer
cfInfoBuckets :: Integer
      -- ^ Number of buckets in the filter.
    , CFInfo -> Integer
cfInfoFilters :: Integer
      -- ^ Number of sub-filters.
    , CFInfo -> Integer
cfInfoItemsInserted :: Integer
      -- ^ Number of inserted items tracked by the filter.
    , CFInfo -> Integer
cfInfoItemsDeleted :: Integer
      -- ^ Number of deleted items tracked by the filter.
    , CFInfo -> Integer
cfInfoBucketSize :: Integer
      -- ^ Number of entries per bucket.
    , CFInfo -> Integer
cfInfoExpansion :: Integer
      -- ^ Expansion rate used when additional sub-filters are created.
    , CFInfo -> Integer
cfInfoMaxIterations :: Integer
      -- ^ Maximum number of displacement attempts during insertion.
    } deriving (Int -> CFInfo -> ShowS
[CFInfo] -> ShowS
CFInfo -> String
(Int -> CFInfo -> ShowS)
-> (CFInfo -> String) -> ([CFInfo] -> ShowS) -> Show CFInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CFInfo -> ShowS
showsPrec :: Int -> CFInfo -> ShowS
$cshow :: CFInfo -> String
show :: CFInfo -> String
$cshowList :: [CFInfo] -> ShowS
showList :: [CFInfo] -> ShowS
Show, CFInfo -> CFInfo -> Bool
(CFInfo -> CFInfo -> Bool)
-> (CFInfo -> CFInfo -> Bool) -> Eq CFInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CFInfo -> CFInfo -> Bool
== :: CFInfo -> CFInfo -> Bool
$c/= :: CFInfo -> CFInfo -> Bool
/= :: CFInfo -> CFInfo -> Bool
Eq)

instance RedisResult CFInfo where
    decode :: Reply -> Either Reply CFInfo
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)]
        cfInfoSize <- decodeField "Size" fields
        cfInfoBuckets <- decodeField "Number of buckets" fields
        cfInfoFilters <- decodeField "Number of filters" fields
        cfInfoItemsInserted <- decodeField "Number of items inserted" fields
        cfInfoItemsDeleted <- decodeField "Number of items deleted" fields
        cfInfoBucketSize <- decodeField "Bucket size" fields
        cfInfoExpansion <- decodeField "Expansion rate" fields
        cfInfoMaxIterations <- decodeField "Max iterations" fields
        pure CFInfo{..}
      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 CFReserveOpts = CFReserveOpts
    { CFReserveOpts -> Maybe Integer
cfReserveBucketSize :: Maybe Integer
      -- ^ Number of entries per bucket.
    , CFReserveOpts -> Maybe Integer
cfReserveMaxIterations :: Maybe Integer
      -- ^ Maximum number of displacement attempts during insertion.
    , CFReserveOpts -> Maybe Integer
cfReserveExpansion :: Maybe Integer
      -- ^ Expansion rate for newly created sub-filters.
    } deriving (Int -> CFReserveOpts -> ShowS
[CFReserveOpts] -> ShowS
CFReserveOpts -> String
(Int -> CFReserveOpts -> ShowS)
-> (CFReserveOpts -> String)
-> ([CFReserveOpts] -> ShowS)
-> Show CFReserveOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CFReserveOpts -> ShowS
showsPrec :: Int -> CFReserveOpts -> ShowS
$cshow :: CFReserveOpts -> String
show :: CFReserveOpts -> String
$cshowList :: [CFReserveOpts] -> ShowS
showList :: [CFReserveOpts] -> ShowS
Show, CFReserveOpts -> CFReserveOpts -> Bool
(CFReserveOpts -> CFReserveOpts -> Bool)
-> (CFReserveOpts -> CFReserveOpts -> Bool) -> Eq CFReserveOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CFReserveOpts -> CFReserveOpts -> Bool
== :: CFReserveOpts -> CFReserveOpts -> Bool
$c/= :: CFReserveOpts -> CFReserveOpts -> Bool
/= :: CFReserveOpts -> CFReserveOpts -> Bool
Eq)

defaultCFReserveOpts :: CFReserveOpts
defaultCFReserveOpts :: CFReserveOpts
defaultCFReserveOpts = CFReserveOpts
    { cfReserveBucketSize :: Maybe Integer
cfReserveBucketSize = Maybe Integer
forall a. Maybe a
Nothing
    , cfReserveMaxIterations :: Maybe Integer
cfReserveMaxIterations = Maybe Integer
forall a. Maybe a
Nothing
    , cfReserveExpansion :: Maybe Integer
cfReserveExpansion = Maybe Integer
forall a. Maybe a
Nothing
    }

data CFInsertOpts = CFInsertOpts
    { CFInsertOpts -> Maybe Integer
cfInsertCapacity :: Maybe Integer
      -- ^ Initial capacity to use if a new filter is created.
    , CFInsertOpts -> Bool
cfInsertNoCreate :: Bool
      -- ^ Return an error instead of creating the filter when the key does not exist.
    } deriving (Int -> CFInsertOpts -> ShowS
[CFInsertOpts] -> ShowS
CFInsertOpts -> String
(Int -> CFInsertOpts -> ShowS)
-> (CFInsertOpts -> String)
-> ([CFInsertOpts] -> ShowS)
-> Show CFInsertOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CFInsertOpts -> ShowS
showsPrec :: Int -> CFInsertOpts -> ShowS
$cshow :: CFInsertOpts -> String
show :: CFInsertOpts -> String
$cshowList :: [CFInsertOpts] -> ShowS
showList :: [CFInsertOpts] -> ShowS
Show, CFInsertOpts -> CFInsertOpts -> Bool
(CFInsertOpts -> CFInsertOpts -> Bool)
-> (CFInsertOpts -> CFInsertOpts -> Bool) -> Eq CFInsertOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CFInsertOpts -> CFInsertOpts -> Bool
== :: CFInsertOpts -> CFInsertOpts -> Bool
$c/= :: CFInsertOpts -> CFInsertOpts -> Bool
/= :: CFInsertOpts -> CFInsertOpts -> Bool
Eq)

defaultCFInsertOpts :: CFInsertOpts
defaultCFInsertOpts :: CFInsertOpts
defaultCFInsertOpts = CFInsertOpts
    { cfInsertCapacity :: Maybe Integer
cfInsertCapacity = Maybe Integer
forall a. Maybe a
Nothing
    , cfInsertNoCreate :: Bool
cfInsertNoCreate = Bool
False
    }

data CFInsertResult
    = CFInsertAdded
    | CFInsertAlreadyExists
    | CFInsertFilterFull
    deriving (Int -> CFInsertResult -> ShowS
[CFInsertResult] -> ShowS
CFInsertResult -> String
(Int -> CFInsertResult -> ShowS)
-> (CFInsertResult -> String)
-> ([CFInsertResult] -> ShowS)
-> Show CFInsertResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CFInsertResult -> ShowS
showsPrec :: Int -> CFInsertResult -> ShowS
$cshow :: CFInsertResult -> String
show :: CFInsertResult -> String
$cshowList :: [CFInsertResult] -> ShowS
showList :: [CFInsertResult] -> ShowS
Show, CFInsertResult -> CFInsertResult -> Bool
(CFInsertResult -> CFInsertResult -> Bool)
-> (CFInsertResult -> CFInsertResult -> Bool) -> Eq CFInsertResult
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CFInsertResult -> CFInsertResult -> Bool
== :: CFInsertResult -> CFInsertResult -> Bool
$c/= :: CFInsertResult -> CFInsertResult -> Bool
/= :: CFInsertResult -> CFInsertResult -> Bool
Eq)

instance RedisResult CFInsertResult where
    decode :: Reply -> Either Reply CFInsertResult
decode Reply
r = do
        result <- Reply -> Either Reply Integer
forall a. RedisResult a => Reply -> Either Reply a
decode Reply
r :: Either Reply Integer
        case result of
            Integer
1 -> CFInsertResult -> Either Reply CFInsertResult
forall a b. b -> Either a b
Right CFInsertResult
CFInsertAdded
            Integer
0 -> CFInsertResult -> Either Reply CFInsertResult
forall a b. b -> Either a b
Right CFInsertResult
CFInsertAlreadyExists
            -1 -> CFInsertResult -> Either Reply CFInsertResult
forall a b. b -> Either a b
Right CFInsertResult
CFInsertFilterFull
            Integer
_ -> Reply -> Either Reply CFInsertResult
forall a b. a -> Either a b
Left Reply
r

cfReserveOptsToArgs :: CFReserveOpts -> [ByteString]
cfReserveOptsToArgs :: CFReserveOpts -> [ByteString]
cfReserveOptsToArgs CFReserveOpts{Maybe Integer
cfReserveBucketSize :: CFReserveOpts -> Maybe Integer
cfReserveMaxIterations :: CFReserveOpts -> Maybe Integer
cfReserveExpansion :: CFReserveOpts -> Maybe Integer
cfReserveBucketSize :: Maybe Integer
cfReserveMaxIterations :: Maybe Integer
cfReserveExpansion :: Maybe Integer
..} =
    [ByteString]
bucketSizeArg [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
maxIterationsArg [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
expansionArg
  where
    bucketSizeArg :: [ByteString]
bucketSizeArg = [ByteString]
-> (Integer -> [ByteString]) -> Maybe Integer -> [ByteString]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Integer
bucketSize -> [ByteString
"BUCKETSIZE", Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode Integer
bucketSize]) Maybe Integer
cfReserveBucketSize
    maxIterationsArg :: [ByteString]
maxIterationsArg = [ByteString]
-> (Integer -> [ByteString]) -> Maybe Integer -> [ByteString]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Integer
iterations -> [ByteString
"MAXITERATIONS", Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode Integer
iterations]) Maybe Integer
cfReserveMaxIterations
    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
cfReserveExpansion

cfInsertOptsToArgs :: CFInsertOpts -> [ByteString]
cfInsertOptsToArgs :: CFInsertOpts -> [ByteString]
cfInsertOptsToArgs CFInsertOpts{Bool
Maybe Integer
cfInsertCapacity :: CFInsertOpts -> Maybe Integer
cfInsertNoCreate :: CFInsertOpts -> Bool
cfInsertCapacity :: Maybe Integer
cfInsertNoCreate :: Bool
..} =
    [ByteString]
capacityArg [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
noCreateArg
  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
cfInsertCapacity
    noCreateArg :: [ByteString]
noCreateArg = [ByteString
"NOCREATE" | Bool
cfInsertNoCreate]

-- |Adds an item to a Cuckoo filter (<https://redis.io/commands/cf.add>).
--
-- A filter is created automatically if the key does not exist.
--
-- /O(k + i)/, where /k/ is the number of sub-filters and /i/ is maxIterations.
--
-- Since RedisBloom 1.0.0
cfadd
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> ByteString -- ^ Item to add.
    -> m (f Bool)
cfadd :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> ByteString -> m (f Bool)
cfadd ByteString
key ByteString
item = [ByteString] -> m (f Bool)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"CF.ADD", ByteString
key, ByteString
item]

-- |Adds an item to a Cuckoo filter only if it did not already exist (<https://redis.io/commands/cf.addnx>).
--
-- A filter is created automatically if the key does not exist.
--
-- /O(k + i)/, where /k/ is the number of sub-filters and /i/ is maxIterations.
--
-- Since RedisBloom 1.0.0
cfaddnx
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> ByteString -- ^ Item to add.
    -> m (f Bool)
cfaddnx :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> ByteString -> m (f Bool)
cfaddnx ByteString
key ByteString
item = [ByteString] -> m (f Bool)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"CF.ADDNX", ByteString
key, ByteString
item]

-- |Returns the number of times an item might appear in a Cuckoo filter (<https://redis.io/commands/cf.count>).
--
-- Returns @0@ when the key does not exist or the item was not found.
--
-- /O(k)/, where /k/ is the number of sub-filters.
--
-- Since RedisBloom 1.0.0
cfcount
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> ByteString -- ^ Item to count.
    -> m (f Integer)
cfcount :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> ByteString -> m (f Integer)
cfcount ByteString
key ByteString
item = [ByteString] -> m (f Integer)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"CF.COUNT", ByteString
key, ByteString
item]

-- |Deletes an item from a Cuckoo filter (<https://redis.io/commands/cf.del>).
--
-- Returns 'False' when the key does not exist or the item was not found.
--
-- /O(k)/, where /k/ is the number of sub-filters.
--
-- Since RedisBloom 1.0.0
cfdel
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> ByteString -- ^ Item to delete.
    -> m (f Bool)
cfdel :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> ByteString -> m (f Bool)
cfdel ByteString
key ByteString
item = [ByteString] -> m (f Bool)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"CF.DEL", ByteString
key, ByteString
item]

-- |Checks whether an item may exist in a Cuckoo filter (<https://redis.io/commands/cf.exists>).
--
-- Returns 'False' when the key does not exist or the item is definitely absent.
--
-- /O(k)/, where /k/ is the number of sub-filters.
--
-- Since RedisBloom 1.0.0
cfexists
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> ByteString -- ^ Item to check.
    -> m (f Bool)
cfexists :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> ByteString -> m (f Bool)
cfexists ByteString
key ByteString
item = [ByteString] -> m (f Bool)
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest [ByteString
"CF.EXISTS", ByteString
key, ByteString
item]

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

-- |Adds one or more items to a Cuckoo filter, creating it when needed (<https://redis.io/commands/cf.insert>).
--
-- This is equivalent to inserting with default options and automatic creation enabled.
--
-- /O(n * (k + i))/, where /n/ is the number of items, /k/ is the number of sub-filters, and /i/ is maxIterations.
--
-- Since RedisBloom 1.0.0
cfinsert
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> NonEmpty ByteString -- ^ Items to add.
    -> m (f [CFInsertResult])
cfinsert :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty ByteString -> m (f [CFInsertResult])
cfinsert ByteString
key NonEmpty ByteString
items = ByteString
-> NonEmpty ByteString -> CFInsertOpts -> m (f [CFInsertResult])
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString
-> NonEmpty ByteString -> CFInsertOpts -> m (f [CFInsertResult])
cfinsertOpts ByteString
key NonEmpty ByteString
items CFInsertOpts
defaultCFInsertOpts

-- |Adds one or more items to a Cuckoo filter, creating it when needed (<https://redis.io/commands/cf.insert>).
--
-- /O(n * (k + i))/, where /n/ is the number of items, /k/ is the number of sub-filters, and /i/ is maxIterations.
--
-- Since RedisBloom 1.0.0
cfinsertOpts
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> NonEmpty ByteString -- ^ Items to add.
    -> CFInsertOpts -- ^ Optional creation parameters.
    -> m (f [CFInsertResult])
cfinsertOpts :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString
-> NonEmpty ByteString -> CFInsertOpts -> m (f [CFInsertResult])
cfinsertOpts ByteString
key NonEmpty ByteString
items CFInsertOpts
opts =
    [ByteString] -> m (f [CFInsertResult])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [CFInsertResult]))
-> [ByteString] -> m (f [CFInsertResult])
forall a b. (a -> b) -> a -> b
$ [ByteString
"CF.INSERT", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ CFInsertOpts -> [ByteString]
cfInsertOptsToArgs CFInsertOpts
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 Cuckoo filter only if they did not already exist (<https://redis.io/commands/cf.insertnx>).
--
-- This is equivalent to inserting with default options and automatic creation enabled.
--
-- /O(n * (k + i))/, where /n/ is the number of items, /k/ is the number of sub-filters, and /i/ is maxIterations.
--
-- Since RedisBloom 1.0.0
cfinsertnx
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> NonEmpty ByteString -- ^ Items to add.
    -> m (f [CFInsertResult])
cfinsertnx :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty ByteString -> m (f [CFInsertResult])
cfinsertnx ByteString
key NonEmpty ByteString
items = ByteString
-> NonEmpty ByteString -> CFInsertOpts -> m (f [CFInsertResult])
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString
-> NonEmpty ByteString -> CFInsertOpts -> m (f [CFInsertResult])
cfinsertnxOpts ByteString
key NonEmpty ByteString
items CFInsertOpts
defaultCFInsertOpts

-- |Adds one or more items to a Cuckoo filter only if they did not already exist (<https://redis.io/commands/cf.insertnx>).
--
-- /O(n * (k + i))/, where /n/ is the number of items, /k/ is the number of sub-filters, and /i/ is maxIterations.
--
-- Since RedisBloom 1.0.0
cfinsertnxOpts
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> NonEmpty ByteString -- ^ Items to add.
    -> CFInsertOpts -- ^ Optional creation parameters.
    -> m (f [CFInsertResult])
cfinsertnxOpts :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString
-> NonEmpty ByteString -> CFInsertOpts -> m (f [CFInsertResult])
cfinsertnxOpts ByteString
key NonEmpty ByteString
items CFInsertOpts
opts =
    [ByteString] -> m (f [CFInsertResult])
forall (m :: * -> *) (f :: * -> *) a.
(RedisCtx m f, RedisResult a) =>
[ByteString] -> m (f a)
sendRequest ([ByteString] -> m (f [CFInsertResult]))
-> [ByteString] -> m (f [CFInsertResult])
forall a b. (a -> b) -> a -> b
$ [ByteString
"CF.INSERTNX", ByteString
key] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ CFInsertOpts -> [ByteString]
cfInsertOptsToArgs CFInsertOpts
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

-- |Checks whether one or more items may exist in a Cuckoo filter (<https://redis.io/commands/cf.mexists>).
--
-- A 'False' result means the item is definitely absent, or the key does not exist.
--
-- /O(k * n)/, where /k/ is the number of sub-filters and /n/ is the number of items.
--
-- Since RedisBloom 1.0.0
cfmexists
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter.
    -> NonEmpty ByteString -- ^ Items to check.
    -> m (f [Bool])
cfmexists :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> NonEmpty ByteString -> m (f [Bool])
cfmexists 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
"CF.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 Cuckoo filter (<https://redis.io/commands/cf.reserve>).
--
-- The filter will fail if the key already exists.
--
-- /O(1)/
--
-- Since RedisBloom 1.0.0
cfreserve
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter to create.
    -> Integer -- ^ Initial capacity.
    -> m (f Status)
cfreserve :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> Integer -> m (f Status)
cfreserve ByteString
key Integer
capacity = ByteString -> Integer -> CFReserveOpts -> m (f Status)
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> Integer -> CFReserveOpts -> m (f Status)
cfreserveOpts ByteString
key Integer
capacity CFReserveOpts
defaultCFReserveOpts

-- |Creates an empty Cuckoo filter (<https://redis.io/commands/cf.reserve>).
--
-- /O(1)/
--
-- Since RedisBloom 1.0.0
cfreserveOpts
    :: (RedisCtx m f)
    => ByteString -- ^ Key of the Cuckoo filter to create.
    -> Integer -- ^ Initial capacity.
    -> CFReserveOpts -- ^ Bucket and scaling options.
    -> m (f Status)
cfreserveOpts :: forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> Integer -> CFReserveOpts -> m (f Status)
cfreserveOpts ByteString
key Integer
capacity CFReserveOpts
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
"CF.RESERVE", ByteString
key, Integer -> ByteString
forall a. RedisArg a => a -> ByteString
encode Integer
capacity] [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ CFReserveOpts -> [ByteString]
cfReserveOptsToArgs CFReserveOpts
opts