diff --git a/docs/command-reference/compatibility.md b/docs/command-reference/compatibility.md index 141d4b3a..4909f2c5 100644 --- a/docs/command-reference/compatibility.md +++ b/docs/command-reference/compatibility.md @@ -371,17 +371,18 @@ sidebar_position: 0 | | TOPK.COUNT | Fully supported | | | | TOPK.LIST | Fully supported | | | | TOPK.INFO | Fully supported | | -| CF | CF.ADD | Unsupported | | -| | CF.ADDNX | Unsupported | | -| | CF.COUNT | Unsupported | | -| | CF.DEL | Unsupported | | -| | CF.EXISTS | Unsupported | | -| | CF.INFO | Unsupported | | -| | CF.INSERT | Unsupported | | -| | CF.INSERTNX | Unsupported | | +| CF | CF.ADD | Fully supported | | +| | CF.ADDNX | Fully supported | | +| | CF.COMPACT | Fully supported | | +| | CF.COUNT | Fully supported | | +| | CF.DEL | Fully supported | | +| | CF.EXISTS | Fully supported | | +| | CF.INFO | Fully supported | | +| | CF.INSERT | Fully supported | | +| | CF.INSERTNX | Fully supported | | | | CF.LOADCHUNK | Unsupported | | -| | CF.MEXISTS | Unsupported | | -| | CF.RESERVE | Unsupported | | +| | CF.MEXISTS | Fully supported | | +| | CF.RESERVE | Fully supported | | | | CF.SCANDUMP | Unsupported | | | Cluster | ASKING | Unsupported | | | | CLUSTER ADDSLOTS | Unsupported | | diff --git a/docs/command-reference/cuckoo-filter/_category_.yml b/docs/command-reference/cuckoo-filter/_category_.yml new file mode 100644 index 00000000..6a138f18 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/_category_.yml @@ -0,0 +1,4 @@ +position: 1 +label: Cuckoo Filter +link: + type: generated-index diff --git a/docs/command-reference/cuckoo-filter/cf.add.md b/docs/command-reference/cuckoo-filter/cf.add.md new file mode 100644 index 00000000..09fc5401 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.add.md @@ -0,0 +1,49 @@ +--- +description: Learn how to use the CF.ADD command to add an item to a Cuckoo filter in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.ADD + + + +## Syntax + + CF.ADD key item + +**Time complexity:** O(k + i), where k is the number of sub-filters and i is `MAXITERATIONS` + +**ACL categories:** @cuckoo + +Adds a single `item` to the Cuckoo filter at `key`. +If `key` does not exist, a new filter is created with default parameters. + +Unlike [`CF.ADDNX`](./cf.addnx.md), duplicate insertions are allowed — the same item can be added multiple times and will occupy a separate slot each time. +Use `CF.DEL` once per insertion to remove it. + +If the filter is full and expansion is disabled (`EXPANSION 0`), an error is returned. + +## Return + +[Integer reply](https://valkey.io/topics/protocol/#integers): + +- `1` if the item was successfully added. + +If the filter is full and cannot be expanded, an error is returned instead of an integer reply. + +## Examples + +```shell +dragonfly> CF.ADD cf Hello +(integer) 1 + +dragonfly> CF.ADD cf Hello +(integer) 1 + +dragonfly> CF.COUNT cf Hello +(integer) 2 +``` + +## See also + +[`CF.ADDNX`](./cf.addnx.md) | [`CF.INSERT`](./cf.insert.md) | [`CF.EXISTS`](./cf.exists.md) | [`CF.RESERVE`](./cf.reserve.md) diff --git a/docs/command-reference/cuckoo-filter/cf.addnx.md b/docs/command-reference/cuckoo-filter/cf.addnx.md new file mode 100644 index 00000000..4acc7277 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.addnx.md @@ -0,0 +1,51 @@ +--- +description: Learn how to use the CF.ADDNX command to add an item to a Cuckoo filter only if it does not already exist. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.ADDNX + + + +## Syntax + + CF.ADDNX key item + +**Time complexity:** O(k + i), where k is the number of sub-filters and i is `MAXITERATIONS` + +**ACL categories:** @cuckoo + +Adds a single `item` to the Cuckoo filter at `key` only if it does not already exist. +If `key` does not exist, a new filter is created with default parameters. + +Unlike [`CF.ADD`](./cf.add.md), this command checks for the item before inserting. +Because Cuckoo filters can return false positives, `CF.ADDNX` may decline to insert +an item that was never actually added. + +If the filter is full and expansion is disabled (`EXPANSION 0`), an error is returned. + +## Return + +[Integer reply](https://valkey.io/topics/protocol/#integers): + +- `1` if the item was successfully added. +- `0` if the item already exists in the filter (or is a false positive match). + +If the filter is full and cannot be expanded, an error is returned instead of an integer reply. + +## Examples + +```shell +dragonfly> CF.ADDNX cf Hello +(integer) 1 + +dragonfly> CF.ADDNX cf Hello +(integer) 0 + +dragonfly> CF.ADDNX cf World +(integer) 1 +``` + +## See also + +[`CF.ADD`](./cf.add.md) | [`CF.INSERTNX`](./cf.insertnx.md) | [`CF.EXISTS`](./cf.exists.md) | [`CF.RESERVE`](./cf.reserve.md) diff --git a/docs/command-reference/cuckoo-filter/cf.compact.md b/docs/command-reference/cuckoo-filter/cf.compact.md new file mode 100644 index 00000000..564ce485 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.compact.md @@ -0,0 +1,52 @@ +--- +description: Learn how to use the CF.COMPACT command to compact a Cuckoo filter in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.COMPACT + + + +## Syntax + + CF.COMPACT key + +**Time complexity:** O(k), where k is the number of sub-filters + +**ACL categories:** @cuckoo + +Attempts to compact the Cuckoo filter at `key` by consolidating its sub-filters. + +When a filter expands, older sub-filters are kept around until [`CF.DEL`](./cf.del.md) empties +them out. `CF.DEL` already triggers this automatically once deletions exceed 10% of the items in +the filter, so `CF.COMPACT` mainly exists to force the pass on demand, for example after a batch +of deletions. + +## Return + +[Simple string reply](https://valkey.io/topics/protocol/#simple-strings): `OK`. + +[Error reply](https://valkey.io/topics/protocol/#simple-errors): if `key` does not exist or is not a Cuckoo filter. + +## Examples + +```shell +dragonfly> CF.RESERVE cf 4 +OK + +dragonfly> CF.ADD cf Hello +(integer) 1 + +dragonfly> CF.DEL cf Hello +(integer) 1 + +dragonfly> CF.COMPACT cf +OK + +dragonfly> CF.COMPACT no_such_key +(error) no such key +``` + +## See also + +[`CF.DEL`](./cf.del.md) | [`CF.RESERVE`](./cf.reserve.md) | [`CF.INFO`](./cf.info.md) diff --git a/docs/command-reference/cuckoo-filter/cf.count.md b/docs/command-reference/cuckoo-filter/cf.count.md new file mode 100644 index 00000000..7771461e --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.count.md @@ -0,0 +1,50 @@ +--- +description: Learn how to use the CF.COUNT command to count occurrences of an item in a Cuckoo filter in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.COUNT + + + +## Syntax + + CF.COUNT key item + +**Time complexity:** O(k), where k is the number of sub-filters + +**ACL categories:** @cuckoo + +Returns the number of times `item` occurs in the Cuckoo filter at `key`. + +Since [`CF.ADD`](./cf.add.md) allows duplicate insertions, the same item can occupy more than one +slot. `CF.COUNT` reports how many slots currently match `item`, which may include false positives. + +If `key` does not exist, `0` is returned. + +## Return + +[Integer reply](https://valkey.io/topics/protocol/#integers): the number of occurrences of `item` in the filter. + +## Examples + +```shell +dragonfly> CF.ADD cf foo +(integer) 1 + +dragonfly> CF.ADD cf foo +(integer) 1 + +dragonfly> CF.COUNT cf foo +(integer) 2 + +dragonfly> CF.COUNT cf bar +(integer) 0 + +dragonfly> CF.COUNT no_such_key foo +(integer) 0 +``` + +## See also + +[`CF.ADD`](./cf.add.md) | [`CF.EXISTS`](./cf.exists.md) | [`CF.DEL`](./cf.del.md) diff --git a/docs/command-reference/cuckoo-filter/cf.del.md b/docs/command-reference/cuckoo-filter/cf.del.md new file mode 100644 index 00000000..d1d6f4a5 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.del.md @@ -0,0 +1,56 @@ +--- +description: Learn how to use the CF.DEL command to remove an item from a Cuckoo filter in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.DEL + + + +## Syntax + + CF.DEL key item + +**Time complexity:** O(k), where k is the number of sub-filters + +**ACL categories:** @cuckoo + +Removes a single occurrence of `item` from the Cuckoo filter at `key`. + +Unlike Bloom filters, Cuckoo filters support deletion. Only one occurrence is removed per call, +so if `item` was added multiple times, `CF.DEL` must be called once per insertion to fully remove it. + +Deleting an item that was never added, or deleting more times than it was added, can introduce +false negatives for that item. Only delete items that are known to have been added. + +## Return + +[Integer reply](https://valkey.io/topics/protocol/#integers): + +- `1` if the item was found and removed. +- `0` if the item was not found. + +[Error reply](https://valkey.io/topics/protocol/#simple-errors): if `key` does not exist or is not a Cuckoo filter. + +## Examples + +```shell +dragonfly> CF.ADD cf Hello +(integer) 1 + +dragonfly> CF.DEL cf Hello +(integer) 1 + +dragonfly> CF.EXISTS cf Hello +(integer) 0 + +dragonfly> CF.DEL cf Hello +(integer) 0 + +dragonfly> CF.DEL no_such_key Hello +(error) no such key +``` + +## See also + +[`CF.ADD`](./cf.add.md) | [`CF.COUNT`](./cf.count.md) | [`CF.COMPACT`](./cf.compact.md) diff --git a/docs/command-reference/cuckoo-filter/cf.exists.md b/docs/command-reference/cuckoo-filter/cf.exists.md new file mode 100644 index 00000000..002b6994 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.exists.md @@ -0,0 +1,52 @@ +--- +description: Learn how to use the CF.EXISTS command to check if an item exists in a Cuckoo filter in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.EXISTS + + + +## Syntax + + CF.EXISTS key item + +**Time complexity:** O(k), where k is the number of sub-filters + +**ACL categories:** @cuckoo + +Checks whether `item` exists in the Cuckoo filter at `key`. + +Cuckoo filters may return false positives — an item that was never inserted may +still be reported as present due to a fingerprint collision. False negatives are +not possible: if an item was inserted and never deleted, `CF.EXISTS` will always +return `1`. + +If `key` does not exist, `0` is returned. + +## Return + +[Integer reply](https://valkey.io/topics/protocol/#integers): + +- `1` if the item exists (or is a false positive match). +- `0` if the item does not exist. + +## Examples + +```shell +dragonfly> CF.ADD cf Hello +(integer) 1 + +dragonfly> CF.EXISTS cf Hello +(integer) 1 + +dragonfly> CF.EXISTS cf World +(integer) 0 + +dragonfly> CF.EXISTS no_such_key item +(integer) 0 +``` + +## See also + +[`CF.MEXISTS`](./cf.mexists.md) | [`CF.COUNT`](./cf.count.md) | [`CF.ADD`](./cf.add.md) | [`CF.RESERVE`](./cf.reserve.md) diff --git a/docs/command-reference/cuckoo-filter/cf.info.md b/docs/command-reference/cuckoo-filter/cf.info.md new file mode 100644 index 00000000..ef0ab9f8 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.info.md @@ -0,0 +1,68 @@ +--- +description: Learn how to use the CF.INFO command to get information about a Cuckoo filter in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.INFO + + + +## Syntax + + CF.INFO key + +**Time complexity:** O(1) + +**ACL categories:** @cuckoo + +Returns information about the Cuckoo filter at `key`. + +## Return + +[Array reply](https://valkey.io/topics/protocol/#arrays) of alternating field names and values: + +- `Size`: memory used by the filter, in bytes. +- `Number of buckets`: total number of buckets across all sub-filters. +- `Number of filters`: number of sub-filters created due to expansion. +- `Number of items inserted`: total number of items currently in the filter. +- `Number of items deleted`: total number of items deleted from the filter. +- `Bucket size`: number of fingerprint slots per bucket. +- `Expansion rate`: the configured expansion rate. +- `Max iterations`: the configured maximum number of cuckoo-displacement attempts. + +[Error reply](https://valkey.io/topics/protocol/#simple-errors): if `key` does not exist or is not a Cuckoo filter. + +## Examples + +```shell +dragonfly> CF.RESERVE cf 1000 BUCKETSIZE 4 MAXITERATIONS 10 EXPANSION 2 +OK + +dragonfly> CF.ADD cf foo +(integer) 1 + +dragonfly> CF.INFO cf + 1) "Size" + 2) (integer) 128 + 3) "Number of buckets" + 4) (integer) 512 + 5) "Number of filters" + 6) (integer) 1 + 7) "Number of items inserted" + 8) (integer) 1 + 9) "Number of items deleted" +10) (integer) 0 +11) "Bucket size" +12) (integer) 4 +13) "Expansion rate" +14) (integer) 2 +15) "Max iterations" +16) (integer) 10 + +dragonfly> CF.INFO no_such_key +(error) no such key +``` + +## See also + +[`CF.RESERVE`](./cf.reserve.md) | [`CF.COUNT`](./cf.count.md) diff --git a/docs/command-reference/cuckoo-filter/cf.insert.md b/docs/command-reference/cuckoo-filter/cf.insert.md new file mode 100644 index 00000000..7049df39 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.insert.md @@ -0,0 +1,59 @@ +--- +description: Learn how to use the CF.INSERT command to add multiple items to a Cuckoo filter in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.INSERT + + + +## Syntax + + CF.INSERT key [CAPACITY capacity] [NOCREATE] ITEMS item [item ...] + +**Time complexity:** O(k * n), where k is the number of sub-filters and n is the number of items + +**ACL categories:** @cuckoo + +Adds one or more items to the Cuckoo filter at `key`, creating it first if it doesn't exist. + +Like [`CF.ADD`](./cf.add.md), duplicate insertions are allowed. + +## Parameters + +| Parameter | Default | Description | +|--------------|---------|-------------------------------------------------------------------------------------------------| +| `key` | | The name of the filter. | +| `CAPACITY` | `1024` | Initial capacity to use if the filter is created by this command. Ignored if `key` already exists. | +| `NOCREATE` | | If set, the filter must already exist; otherwise an error is returned instead of creating it. | +| `ITEMS` | | One or more items to add. Required. | + +## Return + +[Array reply](https://valkey.io/topics/protocol/#arrays) of [Integer replies](https://valkey.io/topics/protocol/#integers), one per item, in the same order as the input: + +- `1` if the item was successfully added. +- `-1` if the filter is full and the item could not be added. + +[Error reply](https://valkey.io/topics/protocol/#simple-errors): if `NOCREATE` is set and `key` does not exist, or `CAPACITY` is `0`. + +## Examples + +```shell +dragonfly> CF.INSERT cf ITEMS Hello World +1) (integer) 1 +2) (integer) 1 + +dragonfly> CF.INSERT cf CAPACITY 500 ITEMS foo +1) (integer) 1 + +dragonfly> CF.INSERT cf NOCREATE ITEMS bar +1) (integer) 1 + +dragonfly> CF.INSERT no_such_key NOCREATE ITEMS bar +(error) no such key +``` + +## See also + +[`CF.INSERTNX`](./cf.insertnx.md) | [`CF.ADD`](./cf.add.md) | [`CF.RESERVE`](./cf.reserve.md) diff --git a/docs/command-reference/cuckoo-filter/cf.insertnx.md b/docs/command-reference/cuckoo-filter/cf.insertnx.md new file mode 100644 index 00000000..cba37e45 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.insertnx.md @@ -0,0 +1,58 @@ +--- +description: Learn how to use the CF.INSERTNX command to add multiple items to a Cuckoo filter without duplicates in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.INSERTNX + + + +## Syntax + + CF.INSERTNX key [CAPACITY capacity] [NOCREATE] ITEMS item [item ...] + +**Time complexity:** O(k * n), where k is the number of sub-filters and n is the number of items + +**ACL categories:** @cuckoo + +Adds one or more items to the Cuckoo filter at `key`, creating it first if it doesn't exist. + +Unlike [`CF.INSERT`](./cf.insert.md), an item is only added if it doesn't already exist in the filter. + +## Parameters + +| Parameter | Default | Description | +|--------------|---------|-------------------------------------------------------------------------------------------------| +| `key` | | The name of the filter. | +| `CAPACITY` | `1024` | Initial capacity to use if the filter is created by this command. Ignored if `key` already exists. | +| `NOCREATE` | | If set, the filter must already exist; otherwise an error is returned instead of creating it. | +| `ITEMS` | | One or more items to add. Required. | + +## Return + +[Array reply](https://valkey.io/topics/protocol/#arrays) of [Integer replies](https://valkey.io/topics/protocol/#integers), one per item, in the same order as the input: + +- `1` if the item was successfully added. +- `0` if the item already exists in the filter. +- `-1` if the filter is full and the item could not be added. + +[Error reply](https://valkey.io/topics/protocol/#simple-errors): if `NOCREATE` is set and `key` does not exist, or `CAPACITY` is `0`. + +## Examples + +```shell +dragonfly> CF.INSERTNX cf ITEMS Hello World +1) (integer) 1 +2) (integer) 1 + +dragonfly> CF.INSERTNX cf ITEMS Hello Again +1) (integer) 0 +2) (integer) 1 + +dragonfly> CF.INSERTNX no_such_key NOCREATE ITEMS bar +(error) no such key +``` + +## See also + +[`CF.INSERT`](./cf.insert.md) | [`CF.ADDNX`](./cf.addnx.md) | [`CF.RESERVE`](./cf.reserve.md) diff --git a/docs/command-reference/cuckoo-filter/cf.mexists.md b/docs/command-reference/cuckoo-filter/cf.mexists.md new file mode 100644 index 00000000..aba408b1 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.mexists.md @@ -0,0 +1,53 @@ +--- +description: Learn how to use the CF.MEXISTS command to check multiple items in a Cuckoo filter in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.MEXISTS + + + +## Syntax + + CF.MEXISTS key item [item ...] + +**Time complexity:** O(k * n), where k is the number of sub-filters and n is the number of items + +**ACL categories:** @cuckoo + +Checks whether one or more items exist in the Cuckoo filter at `key`. +Returns one reply per item in the same order as the input. + +Like [`CF.EXISTS`](./cf.exists.md), false positives are possible but false negatives are not. +If `key` does not exist, `0` is returned for every item. + +## Return + +[Array reply](https://valkey.io/topics/protocol/#arrays) of [Integer replies](https://valkey.io/topics/protocol/#integers), one per item: + +- `1` if the item exists (or is a false positive match). +- `0` if the item does not exist. + +## Examples + +```shell +dragonfly> CF.ADD cf Hello +(integer) 1 + +dragonfly> CF.ADD cf World +(integer) 1 + +dragonfly> CF.MEXISTS cf Hello World Missing +1) (integer) 1 +2) (integer) 1 +3) (integer) 0 + +dragonfly> CF.MEXISTS no_such_key a b c +1) (integer) 0 +2) (integer) 0 +3) (integer) 0 +``` + +## See also + +[`CF.EXISTS`](./cf.exists.md) | [`CF.INSERT`](./cf.insert.md) | [`CF.ADD`](./cf.add.md) | [`CF.RESERVE`](./cf.reserve.md) diff --git a/docs/command-reference/cuckoo-filter/cf.reserve.md b/docs/command-reference/cuckoo-filter/cf.reserve.md new file mode 100644 index 00000000..e6ff2f80 --- /dev/null +++ b/docs/command-reference/cuckoo-filter/cf.reserve.md @@ -0,0 +1,54 @@ +--- +description: Learn how to use the CF.RESERVE command to create a Cuckoo filter in Dragonfly. +--- +import PageTitle from '@site/src/components/PageTitle'; + +# CF.RESERVE + + + +## Syntax + + CF.RESERVE key capacity [BUCKETSIZE bucketsize] [MAXITERATIONS maxiterations] [EXPANSION expansion] + +**Time complexity:** O(1) + +**ACL categories:** @cuckoo + +Creates a new Cuckoo filter at `key` with an initial capacity of at least `capacity` items. +If `key` already exists, an error is returned. + +Unlike Bloom filters, Cuckoo filters support deletion of individual items. + +## Parameters + +| Parameter | Default | Description | +|-----------------|---------|--------------------------------------------------------------------------------------------------------------------| +| `key` | | The name of the filter. | +| `capacity` | | Estimated number of items the filter should hold. Actual capacity is rounded up to the next power of two. | +| `BUCKETSIZE` | `2` | Number of fingerprint slots per bucket. Higher values improve fill rate but increase false positive probability. | +| `MAXITERATIONS` | `20` | Maximum number of cuckoo-displacement attempts before declaring the filter full. Must be between 1 and 65535. | +| `EXPANSION` | `1` | When the filter is full, a new sub-filter of size `capacity * expansion` is created. `0` disables expansion. | + +## Return + +[Simple string reply](https://valkey.io/topics/protocol/#simple-strings): `OK` if the filter was created successfully. + +[Error reply](https://valkey.io/topics/protocol/#simple-errors): if `key` already exists, or a parameter is out of range. + +## Examples + +```shell +dragonfly> CF.RESERVE cf 1000 +OK + +dragonfly> CF.RESERVE cf 1000 +(error) item exists + +dragonfly> CF.RESERVE cf_custom 10000 BUCKETSIZE 4 MAXITERATIONS 50 EXPANSION 2 +OK +``` + +## See also + +[`CF.ADD`](./cf.add.md) | [`CF.ADDNX`](./cf.addnx.md) | [`CF.INSERT`](./cf.insert.md) | [`CF.INFO`](./cf.info.md)