Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/command-reference/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ sidebar_position: 0
| | <span class="command">SELECT</span> | <span class="support supported">Fully supported</span> |
| <span class="family">Generic</span> | <span class="command">COPY</span> | <span class="support partial">Partially supported</span> |
| | <span class="command">DEL</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">DELEX</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">DUMP</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">EXISTS</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">EXPIRE</span> | <span class="support supported">Fully supported</span> |
Expand Down Expand Up @@ -267,6 +268,7 @@ sidebar_position: 0
| <span class="family">String</span> | <span class="command">APPEND</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">DECR</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">DECRBY</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">DIGEST</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">GET</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">GETEX</span> | <span class="support supported">Fully supported</span> |
| | <span class="command">GETDEL</span> | <span class="support supported">Fully supported</span> |
Expand Down
184 changes: 184 additions & 0 deletions docs/command-reference/generic/delex.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
---
description: Learn how to use Redis DELEX command for conditional key deletion.
---

import PageTitle from '@site/src/components/PageTitle';

# DELEX

<PageTitle title="Redis DELEX Command (Documentation) | Dragonfly" />

## Introduction

The `DELEX` command provides conditional key deletion based on value or digest comparison.
It enables atomic conditional operations, allowing you to delete keys only when specific conditions are met.
This is useful for implementing optimistic locking patterns and ensuring data consistency.

**Availability:** Dragonfly v1.37.0 and later.

## Syntax

```shell
DELEX key [IFEQ value | IFNE value | IFDEQ digest | IFDNE digest]
```

**Time complexity:**
- O(1) when no condition is specified
- O(min(M,N)) for value comparisons (IFEQ/IFNE) where M and N are value lengths
- O(N) for digest comparisons (IFDEQ/IFDNE) where N is the length of the stored string value

**ACL categories:** @keyspace, @write, @fast

## Parameter Explanations

- `key`: The key to conditionally delete. Must be a string type for conditional operations.
- `IFEQ value` (optional): Delete the key only if its value matches the provided value.
- `IFNE value` (optional): Delete the key only if its value differs from the provided value.
- `IFDEQ digest` (optional): Delete the key only if its digest matches the provided digest (16-character hex string).
- `IFDNE digest` (optional): Delete the key only if its digest differs from the provided digest (16-character hex string).

## Return Values

- Returns `1` if the key was deleted.
- Returns `0` if the key was not deleted (condition not met or key doesn't exist).

## Code Examples

### Basic DELEX Without Condition

Without a condition, `DELEX` behaves like the standard [`DEL`](./del.md) command:

```shell
dragonfly$> SET mykey "hello"
OK
dragonfly$> DELEX mykey
(integer) 1
dragonfly$> EXISTS mykey
(integer) 0
```

### DELEX with IFEQ (Delete If Equal)

Delete the key only if the value matches:

```shell
dragonfly$> SET mykey "hello"
OK
dragonfly$> DELEX mykey IFEQ "hello"
(integer) 1

dragonfly$> SET mykey "hello"
OK
dragonfly$> DELEX mykey IFEQ "world"
(integer) 0
dragonfly$> GET mykey
"hello"
```

### DELEX with IFNE (Delete If Not Equal)

Delete the key only if the value differs:

```shell
dragonfly$> SET mykey "hello"
OK
dragonfly$> DELEX mykey IFNE "world"
(integer) 1

dragonfly$> SET mykey "hello"
OK
dragonfly$> DELEX mykey IFNE "hello"
(integer) 0
dragonfly$> GET mykey
"hello"
```

### DELEX with IFDEQ (Delete If Digest Equal)

Delete the key only if the digest matches:

```shell
dragonfly$> SET mykey "test"
OK
dragonfly$> DIGEST mykey
"9ec9f7918d7dfc40"
dragonfly$> DELEX mykey IFDEQ "9ec9f7918d7dfc40"
(integer) 1

dragonfly$> SET mykey "test"
OK
dragonfly$> DELEX mykey IFDEQ "0000000000000000"
(integer) 0
dragonfly$> GET mykey
"test"
```

### DELEX with IFDNE (Delete If Digest Not Equal)

Delete the key only if the digest differs:

```shell
dragonfly$> SET mykey "test"
OK
dragonfly$> DIGEST mykey
"9ec9f7918d7dfc40"
dragonfly$> DELEX mykey IFDNE "0000000000000000"
(integer) 1

dragonfly$> SET mykey "test"
OK
dragonfly$> DELEX mykey IFDNE "9ec9f7918d7dfc40"
(integer) 0
dragonfly$> GET mykey
"test"
```

### Optimistic Locking Pattern

Use `DELEX` for optimistic locking to ensure data hasn't changed:

```shell
dragonfly$> SET counter "100"
OK
dragonfly$> DIGEST counter
"e3cd843a18868415"

# Later, delete only if the value hasn't changed
dragonfly$> DELEX counter IFDEQ "e3cd843a18868415"
(integer) 1
```

## Best Practices

- Use `DELEX` with digest comparisons (`IFDEQ`/`IFDNE`) for efficient optimistic locking without transferring full values.
- Use value comparisons (`IFEQ`/`IFNE`) when you need exact value matching.
- Always check the return value to determine if the deletion was successful.
- For optimistic locking, compute the digest first with [`DIGEST`](../strings/digest.md), then use `DELEX IFDEQ` to ensure atomicity.

## Common Mistakes

- Providing only a condition without a value/digest (e.g., `DELEX key IFEQ`) will result in a syntax error.
- Using `DELEX` with conditional options on non-string keys will result in a `WRONGTYPE` error.
- Forgetting that `DELEX` returns `0` when the condition is not met, not an error.

## FAQs

### What happens if the key doesn't exist?

If the key doesn't exist, `DELEX` returns `0` regardless of the condition specified.

### Can DELEX be used with non-string values?

For basic `DELEX key` without conditions, yes. However, conditional operations (IFEQ, IFNE, IFDEQ, IFDNE) only work with string values.

### Is DELEX atomic?

Yes, `DELEX` is atomic. The check and delete operation happens as a single atomic operation within Dragonfly's transaction framework.

### Is DELEX replicated?

Yes, `DELEX` operations are journaled and replicated to replicas, ensuring consistency across your cluster.

### How is DELEX different from DEL?

`DELEX` extends [`DEL`](./del.md) by adding conditional deletion based on value or digest matching. Without conditions, `DELEX key` behaves identically to `DEL key`.
121 changes: 121 additions & 0 deletions docs/command-reference/strings/digest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
description: Learn how to use Redis DIGEST command to compute hash digest of string values.
---

import PageTitle from '@site/src/components/PageTitle';

# DIGEST

<PageTitle title="Redis DIGEST Command (Documentation) | Dragonfly" />

## Introduction

The `DIGEST` command returns a hash digest for the value stored at a specified key.
It uses the XXH3 hashing algorithm to compute a 64-bit hash and returns it as a 16-character hexadecimal string.
This command is useful for comparing values without transferring the full content, implementing checksums, or detecting changes.

**Availability:** Dragonfly v1.37.0 and later.

## Syntax

```shell
DIGEST key
```

**Time complexity:** O(N) where N is the length of the string value

**ACL categories:** @read, @string, @fast

## Parameter Explanations

- `key`: The key whose value should be hashed. Must be a string type.

## Return Values

- Returns a 16-character hexadecimal string representing the XXH3 64-bit hash of the value.
- Returns `nil` if the key does not exist.
- Returns an error if the key exists but holds a non-string value type.

## Code Examples

### Basic Example

Compute digest of a string value:

```shell
dragonfly$> SET mykey "Hello, Dragonfly!"
OK
dragonfly$> DIGEST mykey
"063b4909128e92b7"
```

### Non-Existent Key

If the key does not exist, `DIGEST` returns `nil`:

```shell
dragonfly$> DIGEST non_existent_key
(nil)
```

### Digest Consistency

The same value always produces the same digest:

```shell
dragonfly$> SET key1 "test"
OK
dragonfly$> SET key2 "test"
OK
dragonfly$> DIGEST key1
"9ec9f7918d7dfc40"
dragonfly$> DIGEST key2
"9ec9f7918d7dfc40"
```

### Different Values Produce Different Digests

```shell
dragonfly$> SET key1 "hello"
OK
dragonfly$> SET key2 "world"
OK
dragonfly$> DIGEST key1
"9555e8555c62dcfd"
dragonfly$> DIGEST key2
"d6476c25083d69be"
```

### Error on Wrong Type

```shell
dragonfly$> LPUSH mylist "item"
(integer) 1
dragonfly$> DIGEST mylist
(error) WRONGTYPE Operation against a key holding the wrong kind of value
```

## Best Practices

- Use `DIGEST` to compare values efficiently without transferring full content over the network.
- Implement change detection mechanisms by storing and comparing digests.
- Use with [`DELEX`](../generic/delex.md) `IFDEQ`/`IFDNE` for conditional deletions based on digest matching.

## Common Mistakes

- Attempting to use `DIGEST` on non-string keys will result in a `WRONGTYPE` error.
- Assuming different values might produce the same digest (hash collisions are extremely rare with XXH3).

## FAQs

### What hashing algorithm does DIGEST use?

`DIGEST` uses the XXH3 algorithm, which is a fast, non-cryptographic hash function that produces a 64-bit hash value.

### Is DIGEST suitable for cryptographic purposes?

No, `DIGEST` uses XXH3 which is not a cryptographic hash function. For cryptographic purposes, use dedicated cryptographic hash functions.

### Can DIGEST work with integer-encoded strings?

Yes, `DIGEST` handles all string encodings including raw strings and integer-encoded strings.
2 changes: 1 addition & 1 deletion src/components/CompatibilityTable/data.json

Large diffs are not rendered by default.